working start of new effect system
| -rw-r--r-- | src/build/builders/core/struct.rs | 36 | ||||
| -rw-r--r-- | src/effect.rs | 145 | ||||
| -rw-r--r-- | src/lib.rs | 22 | ||||
| -rw-r--r-- | src/macros/build.rs | 32 | ||||
| -rw-r--r-- | src/walk/walkers/core/struct.rs | 21 | ||||
| -rw-r--r-- | tests/builder_struct.rs | 77 |
6 files changed, 220 insertions, 113 deletions
diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index fa22457..2da2879 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -1,7 +1,7 @@ use crate::{ any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName}, any_trait, - effect::{Effect, ObjSafe, Adapters}, + effect::{Adapters, Effect, ObjSafe}, hkt::Marker, protocol::{ visitor::{ @@ -87,26 +87,28 @@ where where Self: 'a, { - I::new_builders(seed).map(|builders| { - Self { - builders, - // Start in tuple mode until a struct or map tag is visited. - mode: StructMode::Tuple, - _generics: Default::default(), - } - }).into() + I::new_builders(seed) + .map(|builders| { + Self { + builders, + // Start in tuple mode until a struct or map tag is visited. + mode: StructMode::Tuple, + _generics: Default::default(), + } + }) + .into() } fn build<'a>(self) -> ObjSafe<'a, Result<Self::Value, Self::Error>, E> where Self: 'a, { - I::from_builders(self.builders).map(|builders| { - match builders { + I::from_builders(self.builders) + .map(|builders| match builders { Ok(value) => Ok(value), Err(err) => Err(StructError { error: err }), - } - }).into() + }) + .into() } fn as_visitor(&mut self) -> DynVisitor<'_, 'ctx> { @@ -140,12 +142,10 @@ where E::with(NoopVisitor::new(), |noop| { walker .walk(DynVisitor(noop)) - .map(|x| { - x.to_continue() - .into() - }) + .map(|x| x.to_continue().into()) .into() - }).into() + }) + .into() } } diff --git a/src/effect.rs b/src/effect.rs index b0203bc..9207441 100644 --- a/src/effect.rs +++ b/src/effect.rs @@ -39,10 +39,10 @@ use crate::{higher_ranked_trait, higher_ranked_type, hkt::Marker}; // } // pub mod Effective { -// +// // } // -pub trait Adapters<'lt>: Into<<Self::Effect as Effect>::ObjSafe<'lt, Self::T>> + 'lt { +pub trait Adapters<'lt>: Into<ObjSafe<'lt, Self::T, Self::Effect>> + 'lt { type Effect: Effect; type T: 'lt; @@ -56,43 +56,89 @@ pub trait Adapters<'lt>: Into<<Self::Effect as Effect>::ObjSafe<'lt, Self::T>> + 'lt: 'a; } +pub trait ForLt<'a, Output: 'a, B> { + type Effect: Effect; + + type T: Adapters<'a, Effect = Self::Effect, T = Output>; +} + +pub trait Hkt { + type Effect: Effect; + + type T<Output, B>: for<'a> ForLt<'a, Output, &'a (Output, B), Effect = Self::Effect>; +} + +pub trait ForLtFn<'a, E: Effect> { + type T<Input: 'a, Output: 'a, F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, E>>: Adapters<'a, Effect = E, T = Output>; +} + +pub trait HktFn<E: Effect>: for<'a> ForLtFn<'a, E> {} + /// Trait for effects. pub trait Effect: Sized + Send + Sync + 'static { - type ObjSafe<'a, T: 'a>: Adapters<'a, Effect = Self, T = T>; + type ObjSafe: Hkt<Effect = Self>; - type Ready<'a, T: 'a>: Adapters<'a, Effect = Self, T = T>; + type Ready: Hkt<Effect = Self>; - fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T>; + fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T; - type With<'a, T: 'a, R: 'a, F: 'a + FnOnce(&mut T) -> R>: Adapters<'a, Effect = Self, T = R>; + type With: HktFn<Self>; - fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> Self::With<'a, T, R::T, F> - where - R: Adapters<'a, Effect = Self>, - F: FnOnce(&mut T) -> R; + fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Self>>::T<T, R, F> + where + F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>; } -pub type ObjSafe<'a, T, E> = <E as Effect>::ObjSafe<'a, T>; +pub type ObjSafe<'a, T, E> = + <<<E as Effect>::ObjSafe as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T; pub enum Blocking {} +pub enum ValueHkt {} + +impl Hkt for ValueHkt { + type Effect = Blocking; + + type T<Output, B> = ValueHrt<Output, B>; +} + +pub struct ValueHrt<T, B>(Marker<(T, B)>); + +impl<'a, T, B> ForLt<'a, T, &'a (T, B)> for ValueHrt<T, B> { + type Effect = Blocking; + + type T = Value<T>; +} + +pub enum WithHkt {} + +impl HktFn<Blocking> for WithHkt {} + +impl<'a> ForLtFn<'a, Blocking> for WithHkt { + type T< + Input: 'a, + Output: 'a, + F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Blocking>, + > = Value<Output>; +} + impl Effect for Blocking { - type ObjSafe<'a, T: 'a> = Value<T>; + type ObjSafe = ValueHkt; - type Ready<'a, T: 'a> = Value<T>; + type Ready = ValueHkt; - fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T> { + fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T { Value(x) } - type With<'a, T: 'a, R: 'a, F: 'a + FnOnce(&mut T) -> R> = Value<R>; + type With = WithHkt; - fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> Self::With<'a, T, R::T, F> - where - R: Adapters<'a, Effect = Self>, - F: FnOnce(&mut T) -> R { + fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Blocking>>::T<T, R, F> + where + F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>, + { let mut ctx = x; - Value(f(&mut ctx)) + f(&mut ctx) } } @@ -114,21 +160,71 @@ impl<'b, U: 'b> Adapters<'b> for Value<U> { } } -/* pub enum Async {} impl Effect for Async { - type ObjSafe<'a, T: 'a> = BoxedFuture<'a, T>; + type ObjSafe = BoxedFutureHkt; - type Ready<'a, T: 'a> = AsyncValue<T>; + type Ready = AsyncValueHkt; - fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T> { + fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T { AsyncValue(x) } + + type With = AsyncWithHkt; + + fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> <Self::With as ForLtFn<'a, Self>>::T<T, R, F> + where + F: FnOnce(&mut T) -> ObjSafe<'_, R, Self> { + BoxedFuture(Box::pin(async move { + let mut x = x; + + let fut = f(&mut x).0; + fut.await + })) + } +} + +pub enum BoxedFutureHkt {} + +impl Hkt for BoxedFutureHkt { + type Effect = Async; + + type T<Output, B> = BoxedFutureHrt<Output, B>; +} + +pub struct BoxedFutureHrt<Output, B>(Marker<(Output, B)>); + +impl<'a, Output, B> ForLt<'a, Output, &'a (Output, B)> for BoxedFutureHrt<Output, B> { + type Effect = Async; + + type T = BoxedFuture<'a, Output>; +} + +pub enum AsyncValueHkt {} + +impl Hkt for AsyncValueHkt { + type Effect = Async; + + type T<Output, B> = AsyncValue<Output>; +} + +pub enum AsyncWithHkt {} + +impl HktFn<Async> for AsyncWithHkt {} + +impl<'a> ForLtFn<'a, Async> for AsyncWithHkt { + type T<Input: 'a, Output: 'a, F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Async>> = BoxedFuture<'a, Output>; } pub struct AsyncValue<T>(pub T); +impl<'a, T, B> ForLt<'a, T, &'a (T, B)> for AsyncValue<T> { + type Effect = Async; + + type T = AsyncValue<T>; +} + pub struct BoxedFuture<'a, T: 'a>(pub Pin<Box<dyn Future<Output = T> + 'a>>); impl<'b, U: 'b> Adapters<'b> for AsyncValue<U> { @@ -229,7 +325,6 @@ impl<'a, T: 'a> From<AsyncValue<T>> for BoxedFuture<'a, T> { BoxedFuture(Box::pin(futures::future::ready(value.0))) } } -*/ /* pub trait ReadyValue: core::future::Future { @@ -130,7 +130,7 @@ macro_rules! Walk { index: usize, value: &'ctx Self::T, visitor: $crate::protocol::DynVisitor<'a, 'ctx>, - ) -> $crate::effect::Future<'a, Result<$crate::Flow, Self::FieldError>, E> { + ) -> $crate::effect::ObjSafe<'a, Result<$crate::Flow, Self::FieldError>, E> { mod fields { enum Fields {$($field),*} @@ -145,16 +145,18 @@ macro_rules! Walk { let walker = $crate::walkers::core::key_value::KeyValueWalker::<$crate::protocol::visitor::TagConst<{ $crate::TAG_FIELD.to_int() }>, _, _>::new($crate::protocol::visitor::TagConst, key_walker, value_walker); - E::map($crate::Walker::<'ctx, E>::walk(walker, visitor), |result| match result { - Ok(_) => { - Ok($crate::Flow::Continue) - } - Err(err) => { - Err(FieldError(FieldErrorKind::$field(err))) - } - }) + todo!() + + // E::map($crate::Walker::<'ctx, E>::walk(walker, visitor), |result| match result { + // Ok(_) => { + // Ok($crate::Flow::Continue) + // } + // Err(err) => { + // Err(FieldError(FieldErrorKind::$field(err))) + // } + // }) })* - _ => E::ready(Ok($crate::Flow::Done)) + _ => E::ready(Ok($crate::Flow::Done)).into() } } } diff --git a/src/macros/build.rs b/src/macros/build.rs index 158a9dc..2734d2d 100644 --- a/src/macros/build.rs +++ b/src/macros/build.rs @@ -1,7 +1,4 @@ -use crate::{ - effect::{Blocking}, - transform, DefaultMode, -}; +use crate::{effect::Blocking, transform, DefaultMode}; #[macro_export] macro_rules! Build { @@ -47,24 +44,27 @@ macro_rules! Build { type Error = Error; type Seed = ($(<$type as $crate::BuilderTypes>::Seed),*); - fn new_builders<'a>(seed: Self::Seed) -> $crate::effect::Future<'a, Self::Builders, E> { + fn new_builders<'a>(seed: Self::Seed) -> $crate::effect::ObjSafe<'a, Self::Builders, E> { let ($($field),*) = seed; - E::wrap(async move { - Builders { - $($field: $crate::Builder::<E>::from_seed($field).await),* - } - }) + todo!(); + + // E::wrap(async move { + // Builders { + // $($field: $crate::Builder::<E>::from_seed($field).await),* + // } + // }) } - fn from_builders<'a>(builders: Self::Builders) -> $crate::effect::Future<'a, Result<Self::T, Self::Error>, E> { + fn from_builders<'a>(builders: Self::Builders) -> $crate::effect::ObjSafe<'a, Result<Self::T, Self::Error>, E> { use $crate::Builder; - E::wrap(async { - Ok($name { - $($field: builders.$field.build().await.map_err(Error::$field)?),* - }) - }) + todo!(); + // E::wrap(async { + // Ok($name { + // $($field: builders.$field.build().await.map_err(Error::$field)?),* + // }) + // }) } fn as_visitor<'a>( diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs index 81e6950..46ac3a6 100644 --- a/src/walk/walkers/core/struct.rs +++ b/src/walk/walkers/core/struct.rs @@ -232,7 +232,8 @@ where > { E::ready(Ok(TagKnown { kind_available: Some(true), - })).into() + })) + .into() } } @@ -277,7 +278,8 @@ where > { E::ready(Ok(TagKnown { kind_available: Some(true), - })).into() + })) + .into() } } @@ -315,7 +317,8 @@ where { E::ready(Ok(TagKnown { kind_available: Some(true), - })).into() + })) + .into() } } @@ -360,7 +363,8 @@ where > { E::ready(Ok(TagKnown { kind_available: Some(true), - })).into() + })) + .into() } } @@ -406,7 +410,8 @@ where > { E::ready(Ok(TagKnown { kind_available: Some(true), - })).into() + })) + .into() } } @@ -469,7 +474,8 @@ where _ => Ok(TagKnown { kind_available: Some(false), }), - }).into() + }) + .into() } } @@ -528,7 +534,8 @@ where E::ready(Ok(SequenceKnown { len: (len, Some(len)), - })).into() + })) + .into() } } diff --git a/tests/builder_struct.rs b/tests/builder_struct.rs index 27e55f5..aabad24 100644 --- a/tests/builder_struct.rs +++ b/tests/builder_struct.rs @@ -1,7 +1,7 @@ use treaty::{ any::{OwnedStatic, TempBorrowedStatic}, builders::{self, core::r#struct::StructBuilder}, - effect::{Blocking, Effect, Future, ReadyValue}, + effect::{Blocking, Effect, ObjSafe}, protocol::{ visitor::{tags, visit_sequence, visit_tag, visit_value, TagConst, VisitResult}, DynVisitor, @@ -45,26 +45,27 @@ impl<'ctx, M> walkers::core::r#struct::StructTypeInfo<'ctx, M> for Info { index: usize, value: &'ctx Self::T, visitor: DynVisitor<'a, 'ctx>, - ) -> Future<'a, Result<Flow, Self::FieldError>, E> { - E::wrap(async move { - match index { - 0 => { - let walker = <&bool as Walk<M, E>>::into_walker(&value.a); - - assert_eq!(Walker::<E>::walk(walker, visitor).await, Ok(())); - - Ok(Flow::Continue) - } - 1 => { - let walker = <&bool as Walk<M, E>>::into_walker(&value.b); - - assert_eq!(Walker::<E>::walk(walker, visitor).await, Ok(())); - - Ok(Flow::Continue) - } - _ => Ok(Flow::Done), - } - }) + ) -> ObjSafe<'a, Result<Flow, Self::FieldError>, E> { + todo!() + // E::wrap(async move { + // match index { + // 0 => { + // let walker = <&bool as Walk<M, E>>::into_walker(&value.a); + // + // assert_eq!(Walker::<E>::walk(walker, visitor).await, Ok(())); + // + // Ok(Flow::Continue) + // } + // 1 => { + // let walker = <&bool as Walk<M, E>>::into_walker(&value.b); + // + // assert_eq!(Walker::<E>::walk(walker, visitor).await, Ok(())); + // + // Ok(Flow::Continue) + // } + // _ => Ok(Flow::Done), + // } + // }) } } @@ -107,13 +108,14 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo type Error = (); #[inline(always)] - fn from_builders<'a>(builders: Self::Builders) -> Future<'a, Result<Self::T, Self::Error>, E> { - E::wrap(async { - Ok(X { - a: builders.a.build().await.unwrap(), - b: builders.b.build().await.unwrap(), - }) - }) + fn from_builders<'a>(builders: Self::Builders) -> ObjSafe<'a, Result<Self::T, Self::Error>, E> { + todo!() + // E::wrap(async { + // Ok(X { + // a: builders.a.build().await.unwrap(), + // b: builders.b.build().await.unwrap(), + // }) + // }) } #[inline(always)] @@ -130,13 +132,14 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo type Seed = (); #[inline(always)] - fn new_builders<'a>(_seed: Self::Seed) -> Future<'a, Self::Builders, E> { - E::wrap(async { - Fields { - a: Builder::<E>::from_seed(()).await, - b: Builder::<E>::from_seed(()).await, - } - }) + fn new_builders<'a>(_seed: Self::Seed) -> ObjSafe<'a, Self::Builders, E> { + todo!() + // E::wrap(async { + // Fields { + // a: Builder::<E>::from_seed(()).await, + // b: Builder::<E>::from_seed(()).await, + // } + // }) } } @@ -291,7 +294,7 @@ pub mod demo { use crate::Walk; use macro_rules_attribute::derive; use treaty::{ - effect::{Blocking, ReadyValue as _}, + effect::{Blocking}, transform, Build, DefaultMode, }; @@ -313,7 +316,7 @@ pub mod demo { ((), ()), Walk::<DefaultMode, _>::into_walker(&x), ) - .value(); + .0; other.0.unwrap() } |