Diffstat (limited to 'src/build/builders/core/enum.rs')
| -rw-r--r-- | src/build/builders/core/enum.rs | 169 |
1 files changed, 103 insertions, 66 deletions
diff --git a/src/build/builders/core/enum.rs b/src/build/builders/core/enum.rs index a2bcb3b..02fa9fe 100644 --- a/src/build/builders/core/enum.rs +++ b/src/build/builders/core/enum.rs @@ -1,13 +1,18 @@ use core::fmt::{Debug, Display}; +use effectful::bound::{Bool, IsSend, IsSync}; +use effectful::closure::Capture; +use effectful::environment::{DynBind, Environment, NativeForm}; +use effectful::effective::Effective; +use effectful::forward_send_sync; +use effectful::higher_ranked::Mut; + use crate::any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt}; -use crate::effect::{EffectExt, Effective, EffectiveExt}; use crate::protocol::visitor::{DynRecoverableScope, Recoverable, RecoverableProto}; use crate::protocol::AsVisitor; use crate::{ any::{AnyTraitObject, TypeName, TypeNameId}, any_trait, - effect::{Effect, ErasedEffective, Ss}, hkt::Invariant, protocol::{ visitor::{tags, Tag, TagProto, Value, ValueProto, VisitResult}, @@ -16,14 +21,24 @@ use crate::{ Builder, BuilderTypes, DynWalkerObjSafe, Flow, }; -pub struct EnumBuilder<'ctx, Info, Mode, E: Effect> +pub struct EnumBuilder<'ctx, Info, Mode, E: Environment> where Info: EnumBuildInfo<'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 EnumBuilder<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for EnumBuilder<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +enum Inner<'ctx, Info, Mode, E: Environment> where Info: EnumBuildInfo<'ctx, Mode, E>, { @@ -33,31 +48,41 @@ where Value(Result<Info::T, Info::Error>), } -pub trait EnumBuildInfo<'ctx, Mode, E: Effect> { - type Builders: Ss; +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for Inner<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} - type Seed: Ss; +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for Inner<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +pub trait EnumBuildInfo<'ctx, Mode, E: Environment> { + type Builders: DynBind<E>; + + type Seed: DynBind<E>; - type Error: Ss + Debug + Display; + type Error: DynBind<E> + Debug + Display; - type ValueT: TypeName::MemberType; + type ValueT: TypeName::MemberType<E>; - type T: Ss; + type T: DynBind<E>; - type VariantMarker: Ss + Copy + Display; + type VariantMarker: DynBind<E> + Copy + Display; fn new_builder<'a>( seed: Self::Seed, variant: Self::VariantMarker, - ) -> ErasedEffective<'a, Self::Builders, E>; + ) -> NativeForm<'a, Self::Builders, E>; fn finish_builder<'a>( builder: Self::Builders, - ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E>; + ) -> NativeForm<'a, Result<Self::T, Self::Error>, E>; - 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; - fn as_visitor<'a>(builder: &'a mut Self::Builders) -> DynVisitor<'a, 'ctx>; + fn as_visitor<'a>(builder: &'a mut Self::Builders) -> DynVisitor<'a, 'ctx, E>; fn marker_from_name(name: &str) -> Option<Self::VariantMarker>; @@ -66,10 +91,10 @@ pub trait EnumBuildInfo<'ctx, Mode, E: Effect> { fn guess_variant<'a>( seed: Self::Seed, scope: DynRecoverableScope<'a, 'ctx, E>, - ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E>; + ) -> NativeForm<'a, Result<Self::T, Self::Error>, E>; } -impl<'ctx, Info, Mode, E: Effect> BuilderTypes for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> BuilderTypes<E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { @@ -80,20 +105,20 @@ where type Value = Info::T; } -impl<'ctx, Info, Mode, E: Effect> Builder<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Builder<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { - 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, { - E::ready(Self { + E::value(Self { inner: Inner::Seed(seed), - }) + }).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, { @@ -104,16 +129,16 @@ where todo!() } Inner::Builder { builder } => Info::finish_builder(builder), - Inner::Value(value) => E::ready(value), + Inner::Value(value) => E::value(value).cast(), } } } -impl<'ctx, Info, Mode, E: Effect> AsVisitor<'ctx> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> AsVisitor<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx> + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where 'ctx: 'a, { @@ -122,7 +147,7 @@ where } any_trait! { - impl['ctx, Info, Mode, E] EnumBuilder<'ctx, Info, Mode, E> = [ + impl['ctx, Info, Mode][E] EnumBuilder<'ctx, Info, Mode, E> = [ ValueProto<Info::ValueT, E>, TagProto<tags::Variant, E>, RecoverableProto<E> @@ -145,49 +170,49 @@ any_trait! { } else mut { None } where - E: Effect, + E: Environment, Info: EnumBuildInfo<'ctx, Mode, E>, } -impl<'ctx, Info, Mode, E: Effect> Recoverable<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Recoverable<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { fn visit<'a>( &'a mut self, scope: DynRecoverableScope<'a, 'ctx, E>, - ) -> ErasedEffective<'a, VisitResult, E> { + ) -> NativeForm<'a, VisitResult, E> { match core::mem::replace(&mut self.inner, Inner::Temp) { - Inner::Seed(seed) => Info::guess_variant(seed, scope).map(|result| { - self.inner = Inner::Value(result); + Inner::Seed(seed) => Info::guess_variant(seed, scope).map(Capture(self).fun_once(|this, result, _| { + this.inner = Inner::Value(result); Flow::Done.into() - }), + })).cast(), inner => { self.inner = inner; - E::ready(Flow::Continue.into()) + E::value(Flow::Continue.into()).cast() } } } } -impl<'ctx, Info, Mode, E: Effect> Value<'ctx, Info::ValueT, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Value<'ctx, Info::ValueT, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, 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, { self.inner = Inner::Value(Ok(Info::from_value(value))); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } -impl<'ctx, Info, Mode, E: Effect> Tag<'ctx, tags::Variant, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Tag<'ctx, tags::Variant, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { @@ -195,92 +220,104 @@ where &'a mut self, _kind: tags::Variant, walker: DynWalkerObjSafe<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E> { + ) -> NativeForm<'c, VisitResult, E> { let visitor = VariantVisitor::<Info, Mode, E> { marker: None }; - E::as_ctx((visitor, walker), |(visitor, walker)| { + E::value((visitor, walker)) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (visitor, walker), _| { walker.walk(DynVisitor(visitor)).cast() - }) - .then(|((visitor, _), result)| { + })) + .then(Capture(self).fun_once(|this, ((visitor, _), result), _| { if let Some(variant) = visitor.marker { - match core::mem::replace(&mut self.inner, Inner::Temp) { + match core::mem::replace(&mut this.inner, Inner::Temp) { // A variant was given so we need to make the builder for // it. - Inner::Seed(seed) => Info::new_builder(seed, variant).map(move |builder| { - self.inner = Inner::Builder { builder }; + Inner::Seed(seed) => Info::new_builder(seed, variant).map(Capture((this, result)).fun_once(|(this, result), builder, _| { + this.inner = Inner::Builder { builder }; result.to_done().into() - }), + })).cast::<()>(), inner => { - self.inner = inner; - E::ready(result.to_done().into()) + this.inner = inner; + E::value(result.to_done().into()).cast() } } } else { - E::ready(result.to_done().into()) + E::value(result.to_done().into()).cast() } - }) + })) + .cast() } } -struct VariantVisitor<'ctx, Info, Mode, E: Effect> +struct VariantVisitor<'ctx, Info, Mode, E: Environment> where Info: EnumBuildInfo<'ctx, Mode, E>, { marker: Option<Info::VariantMarker>, } +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for VariantVisitor<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for VariantVisitor<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + any_trait! { - impl['ctx, Info, Mode, E] VariantVisitor<'ctx, Info, Mode, E> = [ + impl['ctx, Info, Mode][E] VariantVisitor<'ctx, Info, Mode, E> = [ ValueProto<TempBorrowedStaticHrt<str>, E>, ValueProto<OwnedStatic<u32>, E>, ] where - E: Effect, + E: Environment, Info: EnumBuildInfo<'ctx, Mode, E>, } -impl<'ctx, Info, Mode, E: Effect> Value<'ctx, TempBorrowedStaticHrt<str>, E> +impl<'ctx, Info, Mode, E: Environment> Value<'ctx, TempBorrowedStaticHrt<str>, E> for VariantVisitor<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { fn visit<'a>( &'a mut self, - TempBorrowedStatic(value): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>>, E> + TempBorrowedStatic(value): 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 + Sync + Sized, + TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, 'ctx: 'a, { if let Some(variant) = Info::marker_from_name(value) { self.marker = Some(variant); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } else { - E::ready(Flow::Continue.into()) + E::value(Flow::Continue.into()).cast() } } } -impl<'ctx, Info, Mode, E: Effect> Value<'ctx, OwnedStatic<u32>, E> +impl<'ctx, Info, Mode, E: Environment> Value<'ctx, OwnedStatic<u32>, E> for VariantVisitor<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { fn visit<'a>( &'a mut self, - OwnedStatic(value): TypeName::T<'a, 'ctx, OwnedStatic<u32>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<u32>>>, E> + OwnedStatic(value): TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>>, E> where - TypeName::T<'a, 'ctx, OwnedStatic<u32>>: Send + Sync + Sized, + TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>: Sized, 'ctx: 'a, { if let Some(variant) = Info::marker_from_discriminant(value) { self.marker = Some(variant); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } else { - E::ready(Flow::Continue.into()) + E::value(Flow::Continue.into()).cast() } } } |