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