Diffstat (limited to 'src/build/builders/core/struct.rs')
| -rw-r--r-- | src/build/builders/core/struct.rs | 283 |
1 files changed, 164 insertions, 119 deletions
diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index ef46628..6752acb 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -1,6 +1,12 @@ use core::fmt::{Debug, Display}; -use effectful::{bound::{IsSend, IsSync}, closure::Capture, effective::Effective, environment::{DynBind, Environment, NativeForm}, higher_ranked::Mut, tri}; +use effectful::{ + bound::{IsSend, IsSync}, + effective::Effective, + environment::{DynBind, Environment, NativeForm}, + higher_ranked::Mut, + tri, +}; use crate::{ any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName}, @@ -28,15 +34,19 @@ where inner: Inner<'ctx, Info, Mode, E>, } -unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for StructBuilder<'ctx, Info, Mode, E> +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> +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 @@ -130,15 +140,19 @@ where error: Info::Error, } -unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for 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> +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 @@ -187,12 +201,14 @@ where 'ctx: 'e, { match core::mem::replace(&mut self.inner, Inner::Temp) { - Inner::Seed(seed) => Info::new_builders(seed).map(Capture(self).fun_once(|this, builders, _| { - this.inner = Inner::Builders { - builders, - kind: StructKind::Tuple, - }; - })).cast(), + Inner::Seed(seed) => Info::new_builders(seed) + .map(self, |this, builders| { + this.inner = Inner::Builders { + builders, + kind: StructKind::Tuple, + }; + }) + .cast(), inner => { self.inner = inner; @@ -213,7 +229,8 @@ where { E::value(Self { inner: Inner::Seed(seed), - }).cast() + }) + .cast() } fn build<'a>(self) -> NativeForm<'a, Result<Self::Value, Self::Error>, E> @@ -225,13 +242,14 @@ where Inner::Seed(seed) => { // We may be able to make a value from just the seed. Info::new_builders(seed) - .then(Capture(()).fun_once(|_, builders, _| Info::from_builders(builders))) - .map(Capture(()).fun_once(|_, result, _| result.map_err(StructError::from_field_err))).cast() + .then((), |_, builders| Info::from_builders(builders)) + .map((), |_, result| result.map_err(StructError::from_field_err)) + .cast() } Inner::Builders { builders, .. } => { // Create the value from the builders. Info::from_builders(builders) - .map(Capture(()).fun_once(|_, result, _| result.map_err(StructError::from_field_err))) + .map((), |_, result| result.map_err(StructError::from_field_err)) .cast() } // Use the value as is. @@ -240,7 +258,8 @@ where } } -impl<'ctx, Info, Mode: 'ctx, E: Environment> AsVisitor<'ctx, E> 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>, @@ -282,46 +301,50 @@ where 'ctx: '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. - hint_protocol::<TagProto<tags::Struct, E>, _>( - walker.cast(), - *this, - TagHint { kind: TagConst }, - ) - .cast() - }) - .if_skipped(|(this, walker)| { - // If the struct hint didn't work, - // then hint that the map protocol should be used to switch into - // map-like if the walker supports it. - hint_protocol::<TagProto<tags::Map, E>, _>( - walker.cast(), - *this, - TagHint { kind: TagConst }, - ) - .cast() - }) - .if_not_finished(|(this, walker)| { - // Lastly hint to use a sequence to get the field values. - // We hint with the exact number of fields we are expecting. - hint_protocol::<SequenceProto<E>, _>( - walker.cast(), - *this, - SequenceHint { - len: (Info::FIELD_COUNT, Some(Info::FIELD_COUNT)), - }, - ) + .update((), |_, (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() + }) + .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. + hint_protocol::<TagProto<tags::Struct, E>, _>( + walker.cast(), + *this, + TagHint { kind: TagConst }, + ) + .cast() + }) + .cast::<()>() + .if_skipped((), |_, (this, walker)| { + // If the struct hint didn't work, + // then hint that the map protocol should be used to switch into + // map-like if the walker supports it. + hint_protocol::<TagProto<tags::Map, E>, _>( + walker.cast(), + *this, + TagHint { kind: TagConst }, + ) + .cast() + }) + .cast::<()>() + .if_not_finished((), |_, (this, walker)| { + // Lastly hint to use a sequence to get the field values. + // We hint with the exact number of fields we are expecting. + hint_protocol::<SequenceProto<E>, _>( + walker.cast(), + *this, + SequenceHint { + len: (Info::FIELD_COUNT, Some(Info::FIELD_COUNT)), + }, + ) + .cast() + }) + .cast::<()>() + .map((), |_, (_, x)| x) .cast() - }) - .map(Capture(()).fun_once(|_, (_, x), _| x)) - .cast() } } @@ -365,17 +388,17 @@ where ) -> NativeForm<'e, VisitResult, E> { // If this protocol is used then we need to create the builders. 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; - } + .update((), |_, this| this.make_builders().cast()) + .then(walker, |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() + // Walk the walker so nothing complains. + NoopVisitor::walk_dyn(walker) + }) + .cast() } } @@ -393,16 +416,18 @@ where walker: DynWalkerObjSafe<'walker, 'ctx, E>, ) -> NativeForm<'e, VisitResult, E> { // If this protocol is used then we need to create the builders. - 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; - } + E::value(self) + .update((), |_, this| this.make_builders().cast()) + .then(walker, |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() + // Walk the walker so nothing complains. + NoopVisitor::walk_dyn(walker) + }) + .cast() } } @@ -426,8 +451,8 @@ where { // If this protocol is used then we need to create the builders. E::value(self) - .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, this, _| this.make_builders().cast())) - .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (this, _), _| { + .update((), |_, this| this.make_builders().cast()) + .update(scope, |scope, (this, _)| { match &mut this.inner { // We should treat the sequence as just values. Inner::Builders { @@ -435,22 +460,28 @@ where kind: StructKind::Tuple, } => { // Tuple-like is based on the index of the field. - let mut index = 0; + let index = 0; // Loop through all the fields getting a value for each one. - E::repeat_map((scope, builders), move |(scope, builders)| { - // Get the marker for the field at this index. - let marker = tri!(Info::marker_from_index(index)); - - // Move to the next field for the next iteration. - index += 1; - - // Select the visitor for this field. - let visitor = Info::as_visitor(marker, builders); - - // Visit the next item in the sequence. - scope.next(visitor).map(Flow::to_control_flow).cast() - }) + E::value((scope, builders)) + .repeat(index, |index, (scope, builders)| { + // Get the marker for the field at this index. + let marker = tri!(Info::marker_from_index(*index)); + + // Move to the next field for the next iteration. + *index += 1; + + // Select the visitor for this field. + let visitor = Info::as_visitor(marker, builders); + + // Visit the next item in the sequence. + scope + .next(visitor) + .map((), |_, x| Flow::to_control_flow(x)) + .cast() + }) + .map((), |_, (_, _, x)| x) + .cast::<()>() } // We should treat the sequence as key value pairs. Inner::Builders { @@ -466,24 +497,27 @@ where // Loop through all the elements in the sequence. // Each key value pair will be mapped to a field. - E::repeat_map((visitor, scope), |(visitor, scope)| { - // Visit the next element of the sequence. - // When there are no more items in the sequence then the loop ends. - scope - .next(DynVisitor(visitor)) - .map(Flow::to_control_flow) - .cast() - }) + E::value((visitor, scope)) + .repeat((), |_, (visitor, scope)| { + // Visit the next element of the sequence. + // When there are no more items in the sequence then the loop ends. + scope + .next(DynVisitor(visitor)) + .map((), |_, x| Flow::to_control_flow(x)) + .cast() + }) + .map((), |_, (_, _, x)| x) + .cast() } // 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. _ => E::value(Flow::Done).cast(), } - .map(Into::into) + .map((), |_, x| Into::into(x)) .cast() - })) - .map(Capture(()).fun_once(|_, (_, x), _| x)) + }) + .map((), |_, (_, x)| x) .cast() } } @@ -494,15 +528,19 @@ struct FieldVisitor<'a, 'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> _marker: Marker<E>, } -unsafe impl<'a, 'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for FieldVisitor<'a, 'ctx, Info, Mode, 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> +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> = [ @@ -537,12 +575,15 @@ where _marker: Default::default(), }; - E::ready((self, visitor, walker)) - .as_ctx(|(_, visitor, walker)| walker.walk(DynVisitor(visitor)).cast()) - .map(|((this, visitor, _), flow)| { + E::value((self, visitor, walker)) + .update((), |_, (_, visitor, walker)| { + walker.walk(DynVisitor(visitor)).cast() + }) + .map((), |_, ((this, visitor, _), flow)| { this.marker = visitor.field_marker; flow.to_continue().into() }) + .cast() } } @@ -551,15 +592,19 @@ struct NameVisitor<'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> { _marker: Marker<E>, } -unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for NameVisitor<'ctx, Info, Mode, 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> +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> = [ @@ -586,7 +631,7 @@ where { self.field_marker = I::marker_from_index(index); - E::ready(VisitResult::Control(Flow::Done)) + E::value(VisitResult::Control(Flow::Done)).cast() } } @@ -605,7 +650,7 @@ where { self.field_marker = I::marker_from_name(name); - E::ready(VisitResult::Control(Flow::Done)) + E::value(VisitResult::Control(Flow::Done)).cast() } } @@ -624,6 +669,6 @@ where { self.field_marker = I::marker_from_name(name); - E::ready(VisitResult::Control(Flow::Done)) + E::value(VisitResult::Control(Flow::Done)).cast() } } |