Diffstat (limited to 'src/build/builders/core/struct.rs')
| -rw-r--r-- | src/build/builders/core/struct.rs | 232 |
1 files changed, 142 insertions, 90 deletions
diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index 3675f1c..ef46628 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -1,11 +1,10 @@ use core::fmt::{Debug, Display}; +use effectful::{bound::{IsSend, IsSync}, closure::Capture, effective::Effective, environment::{DynBind, Environment, NativeForm}, higher_ranked::Mut, tri}; + use crate::{ any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName}, any_trait, - effect::{ - Effect, EffectExt as _, Effective, EffectiveExt as _, ErasedEffective, ReadyExt as _, Ss, - }, hkt::Marker, protocol::{ visitor::{ @@ -16,20 +15,30 @@ use crate::{ walker::hint::hint_protocol, AsVisitor, DynVisitor, DynWalker, }, - tri, Builder, BuilderTypes, DynWalkerObjSafe, Flow, + Builder, BuilderTypes, DynWalkerObjSafe, Flow, }; use super::NoopVisitor; /// A builder for a struct. -pub struct StructBuilder<'ctx, Info, Mode, E: Effect> +pub struct StructBuilder<'ctx, Info, Mode, E: Environment> where Info: StructTypeInfo<'ctx, Mode, E>, { inner: Inner<'ctx, Info, Mode, E>, } -enum Inner<'ctx, Info, Mode, E: Effect> +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for StructBuilder<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for StructBuilder<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +enum Inner<'ctx, Info, Mode, E: Environment> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -61,36 +70,36 @@ enum StructKind { /// /// The `Mode` generic allows implementations to change depending on the mode the user gives. /// It is not used by the trait directly. -pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Effect>: 'static { +pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Environment>: 'static { /// A struct of builders for each field. - type Builders: Ss; + type Builders: DynBind<E>; /// The seed value needed to make the builders. - type Seed: Ss; + type Seed: DynBind<E>; /// An enum of the fields. /// /// These markers act in place of the field names. - type FieldMarker: Ss + Copy + Display; + type FieldMarker: DynBind<E> + Copy + Display; /// The error type that can be generated while building the struct. - type Error: Ss + Debug + Display; + type Error: DynBind<E> + Debug + Display; /// The kind of type for enabling the direct value protocol. - type ValueT: TypeName::MemberType; + type ValueT: TypeName::MemberType<E>; /// The struct type this info is for. - type T: Ss; + type T: DynBind<E>; const FIELD_COUNT: usize; /// Create a set of builders from a seed value. - fn new_builders<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self::Builders, E>; + fn new_builders<'a>(seed: Self::Seed) -> NativeForm<'a, Self::Builders, E>; /// Finish building the struct value. fn from_builders<'a>( builders: Self::Builders, - ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E>; + ) -> NativeForm<'a, Result<Self::T, Self::Error>, E>; /// Get the visitor for a field. /// @@ -98,7 +107,7 @@ pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Effect>: 'static { fn as_visitor<'a>( marker: Self::FieldMarker, builders: &'a mut Self::Builders, - ) -> DynVisitor<'a, 'ctx>; + ) -> DynVisitor<'a, 'ctx, E>; /// Get a field marker from the index of the field. /// @@ -109,11 +118,11 @@ pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Effect>: 'static { fn marker_from_name(name: &str) -> Option<Self::FieldMarker>; /// Get the value from the value protocol. - fn from_value<'a>(value: TypeName::T<'a, 'ctx, Self::ValueT>) -> Self::T; + fn from_value<'a>(value: TypeName::T<'a, 'ctx, Self::ValueT, E>) -> Self::T; } /// Error that [`StructBuilder`] returns. -pub struct StructError<'ctx, Info, M, E: Effect> +pub struct StructError<'ctx, Info, M, E: Environment> where Info: StructTypeInfo<'ctx, M, E>, { @@ -121,7 +130,17 @@ where error: Info::Error, } -impl<'ctx, Info, Mode, E: Effect> StructError<'ctx, Info, Mode, E> +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for StructError<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for StructError<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +impl<'ctx, Info, Mode, E: Environment> StructError<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -130,7 +149,7 @@ where } } -impl<'ctx, Info, Mode, E: Effect> Debug for StructError<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Debug for StructError<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -139,7 +158,7 @@ where } } -impl<'ctx, Info, Mode, E: Effect> Display for StructError<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Display for StructError<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -148,7 +167,7 @@ where } } -impl<'ctx, Info, Mode, E: Effect> BuilderTypes for StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> BuilderTypes<E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -159,45 +178,45 @@ where type Value = Info::T; } -impl<'ctx, Info, Mode: 'ctx, E: Effect> StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode: 'ctx, E: Environment> StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { - fn make_builders<'e>(&'e mut self) -> ErasedEffective<'e, (), E> + fn make_builders<'e>(&'e mut self) -> NativeForm<'e, (), E> where 'ctx: 'e, { match core::mem::replace(&mut self.inner, Inner::Temp) { - Inner::Seed(seed) => Info::new_builders(seed).map(|builders| { - self.inner = Inner::Builders { + Inner::Seed(seed) => Info::new_builders(seed).map(Capture(self).fun_once(|this, builders, _| { + this.inner = Inner::Builders { builders, kind: StructKind::Tuple, }; - }), + })).cast(), inner => { self.inner = inner; - ().ready() + E::value(()).cast() } } } } -impl<'ctx, Info, Mode: 'ctx, E: Effect> Builder<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode: 'ctx, E: Environment> Builder<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, { - fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E> + fn from_seed<'a>(seed: Self::Seed) -> NativeForm<'a, Self, E> where Self: 'a, { - Self { + E::value(Self { inner: Inner::Seed(seed), - } - .ready() + }).cast() } - fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E> + fn build<'a>(self) -> NativeForm<'a, Result<Self::Value, Self::Error>, E> where Self: 'a, { @@ -206,25 +225,27 @@ where Inner::Seed(seed) => { // We may be able to make a value from just the seed. Info::new_builders(seed) - .then(|builders| Info::from_builders(builders)) - .map(|result| result.map_err(StructError::from_field_err)) + .then(Capture(()).fun_once(|_, builders, _| Info::from_builders(builders))) + .map(Capture(()).fun_once(|_, result, _| result.map_err(StructError::from_field_err))).cast() } Inner::Builders { builders, .. } => { // Create the value from the builders. Info::from_builders(builders) - .map(|result| result.map_err(StructError::from_field_err)) + .map(Capture(()).fun_once(|_, result, _| result.map_err(StructError::from_field_err))) + .cast() } // Use the value as is. - Inner::Value(value) => Ok(value).ready(), + Inner::Value(value) => E::value(Ok(value)).cast(), } } } -impl<'ctx, Info, Mode: 'ctx, E: Effect> AsVisitor<'ctx> for StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode: 'ctx, E: Environment> AsVisitor<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx> + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where 'ctx: 'a, { @@ -233,36 +254,39 @@ where } any_trait! { - impl['ctx, Info, Mode, E] StructBuilder<'ctx, Info, Mode, E> = [ + impl['ctx, Info, Mode][E] StructBuilder<'ctx, Info, Mode, E> = [ RequestHintProto<E>, ValueProto<Info::ValueT, E>, TagProto<tags::Struct, E>, TagProto<tags::Map, E>, SequenceProto<E> ] where - E: Effect, + E: Environment, Info: StructTypeInfo<'ctx, Mode, E>, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, Mode: 'ctx, } impl<'ctx, Info, Mode: 'ctx, E> RequestHint<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, + E: Environment, { #[inline(always)] fn request_hint<'this: 'e, 'walker: 'e, 'e>( &'this mut self, - walker: DynWalker<'walker, 'ctx>, - ) -> ErasedEffective<'e, VisitResult, E> + walker: DynWalker<'walker, 'ctx, E>, + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'walker, { - E::as_ctx((self, walker), |(this, walker)| { + E::value((self, walker)) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (this, walker), _| { // Start with a hint to use the value protocol to directly transfer the // struct value. hint_protocol::<ValueProto<Info::ValueT, E>, _>(walker.cast(), *this, ()).cast() - }) + })) .if_not_finished(|(this, walker)| { // Next hint that the struct protocol should be used to switch into // map-like if the walker supports it. @@ -296,7 +320,8 @@ where ) .cast() }) - .remove_ctx() + .map(Capture(()).fun_once(|_, (_, x), _| x)) + .cast() } } @@ -306,21 +331,22 @@ where impl<'ctx, Info, Mode, E> Value<'ctx, Info::ValueT, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, + for<'a> TypeName::T<'a, 'ctx, Info::ValueT, E>: DynBind<E>, { fn visit<'a>( &'a mut self, - value: TypeName::T<'a, 'ctx, Info::ValueT>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, Info::ValueT>>, E> + value: TypeName::T<'a, 'ctx, Info::ValueT, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, Info::ValueT, E>>, E> where - TypeName::T<'a, 'ctx, Info::ValueT>: Send + Sync + Sized, + TypeName::T<'a, 'ctx, Info::ValueT, E>: Sized, 'ctx: 'a, { // Get the value from what we got from the walker. self.inner = Inner::Value(Info::from_value(value)); // Since we have the struct value we are done. - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } @@ -330,23 +356,26 @@ where impl<'ctx, Info, Mode: 'ctx, E> Tag<'ctx, tags::Struct, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, { fn visit<'this: 'e, 'walker: 'e, 'e>( &'this mut self, _kind: tags::Struct, walker: DynWalkerObjSafe<'walker, 'ctx, E>, - ) -> ErasedEffective<'e, VisitResult, E> { + ) -> NativeForm<'e, VisitResult, E> { // If this protocol is used then we need to create the builders. - E::as_ctx(self, |this| this.make_builders().cast()).then(|(this, _)| { + E::value(self) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, this, _| this.make_builders().cast())) + .then(Capture(walker).fun_once(|walker, (this, _), _| { if let Inner::Builders { kind, .. } = &mut this.inner { // This signals to go into map mode for the sequence. *kind = StructKind::Map; } // Walk the walker so nothing complains. - NoopVisitor::walk_dyn(walker).cast() - }) + NoopVisitor::walk_dyn(walker) + })) + .cast() } } @@ -356,23 +385,24 @@ where impl<'ctx, Info, Mode: 'ctx, E> Tag<'ctx, tags::Map, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, { fn visit<'this: 'e, 'walker: 'e, 'e>( &'this mut self, _kind: tags::Map, walker: DynWalkerObjSafe<'walker, 'ctx, E>, - ) -> ErasedEffective<'e, VisitResult, E> { + ) -> NativeForm<'e, VisitResult, E> { // If this protocol is used then we need to create the builders. - E::as_ctx(self, |this| this.make_builders().cast()).then(|(this, _)| { + E::value(self).update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, this, _| this.make_builders().cast())).then(Capture(walker).fun_once(|walker, (this, _), _| { if let Inner::Builders { kind, .. } = &mut this.inner { // This signals to go into map mode for the sequence. *kind = StructKind::Map; } // Walk the walker so nothing complains. - NoopVisitor::walk_dyn(walker).cast() - }) + NoopVisitor::walk_dyn(walker) + })) + .cast() } } @@ -385,18 +415,19 @@ where impl<'ctx, Info, Mode: 'ctx, E> Sequence<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, { fn visit<'a: 'c, 'b: 'c, 'c>( &'a mut self, scope: DynSequenceScope<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E> + ) -> NativeForm<'c, VisitResult, E> where 'ctx: 'a + 'b + 'c, { // If this protocol is used then we need to create the builders. - E::as_ctx(self, |this| this.make_builders().cast()) - .as_ctx(|(this, _)| { + E::value(self) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, this, _| this.make_builders().cast())) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (this, _), _| { match &mut this.inner { // We should treat the sequence as just values. Inner::Builders { @@ -447,23 +478,34 @@ where // If we don't have the builders ... we can't do anything. // This would only happen if the walker gives the value directly // then gives a sequence. - _ => Flow::Done.ready(), + _ => E::value(Flow::Done).cast(), } .map(Into::into) .cast() - }) - .remove_ctx() + })) + .map(Capture(()).fun_once(|_, (_, x), _| x)) + .cast() } } -struct FieldVisitor<'a, 'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Effect> { +struct FieldVisitor<'a, 'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> { builders: &'a mut I::Builders, marker: Option<I::FieldMarker>, _marker: Marker<E>, } +unsafe impl<'a, 'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for FieldVisitor<'a, 'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'a, 'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for FieldVisitor<'a, 'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + any_trait! { - impl['ctx, 'a, I, M, E] FieldVisitor<'a, 'ctx, I, M, E> = [ + impl['ctx, 'a, I, M][E] FieldVisitor<'a, 'ctx, I, M, E> = [ TagProto<tags::Key, E>, ] ref { let (_this, _id); @@ -476,20 +518,20 @@ any_trait! { I::as_visitor(marker, this.builders).0.upcast_to_id_mut(id) }) } where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, } impl<'d, 'ctx, I, M, E> Tag<'ctx, tags::Key, E> for FieldVisitor<'d, 'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a: 'c, 'b: 'c, 'c>( &'a mut self, _key: tags::Key, walker: DynWalkerObjSafe<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E> { + ) -> NativeForm<'c, VisitResult, E> { let visitor = NameVisitor::<I, M, E> { field_marker: None, _marker: Default::default(), @@ -504,32 +546,42 @@ where } } -struct NameVisitor<'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Effect> { +struct NameVisitor<'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> { field_marker: Option<I::FieldMarker>, _marker: Marker<E>, } +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for NameVisitor<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for NameVisitor<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + any_trait! { - impl['ctx, I, M, E] NameVisitor<'ctx, I, M, E> = [ + impl['ctx, I, M][E] NameVisitor<'ctx, I, M, E> = [ ValueProto<OwnedStatic<usize>, E>, ValueProto<TempBorrowedStaticHrt<str>, E>, ValueProto<OwnedStatic<&'static str>, E>, ] where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, } impl<'ctx, I, M, E> Value<'ctx, OwnedStatic<usize>, E> for NameVisitor<'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a>( &'a mut self, - OwnedStatic(index): TypeName::T<'a, 'ctx, OwnedStatic<usize>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<usize>>>, E> + OwnedStatic(index): TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>>, E> where - TypeName::T<'a, 'ctx, OwnedStatic<usize>>: Send + Sized, + TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>: Sized, 'ctx: 'a, { self.field_marker = I::marker_from_index(index); @@ -540,15 +592,15 @@ where impl<'ctx, I, M, E> Value<'ctx, TempBorrowedStaticHrt<str>, E> for NameVisitor<'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a>( &'a mut self, - TempBorrowedStatic(name): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>>, E> + TempBorrowedStatic(name): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>, E> where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>: Send + Sized, + TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, 'ctx: 'a, { self.field_marker = I::marker_from_name(name); @@ -559,15 +611,15 @@ where impl<'ctx, I, M, E> Value<'ctx, OwnedStatic<&'static str>, E> for NameVisitor<'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a>( &'a mut self, - OwnedStatic(name): TypeName::T<'a, 'ctx, OwnedStatic<&'static str>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<&'static str>>>, E> + OwnedStatic(name): TypeName::T<'a, 'ctx, OwnedStatic<&'static str>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<&'static str>, E>>, E> where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>: Send + Sized, + TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, 'ctx: 'a, { self.field_marker = I::marker_from_name(name); |