Diffstat (limited to 'src/build/builders/core/struct.rs')
-rw-r--r--src/build/builders/core/struct.rs283
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()
}
}