updated effects
Konnor Andrews 2024-03-17
parent 82a0ea5 · commit 9cd9eec
-rw-r--r--src/build.rs63
-rw-r--r--src/build/builders/core/array.rs33
-rw-r--r--src/build/builders/core/bool.rs28
-rw-r--r--src/build/builders/serde/deserialize.rs34
-rw-r--r--src/build/builders/serde/deserialize_seed.rs39
-rw-r--r--src/hkt.rs12
-rw-r--r--src/lib.rs2
-rw-r--r--src/protocol.rs106
-rw-r--r--src/protocol/visitor/request_hint.rs10
-rw-r--r--src/protocol/visitor/sequence.rs28
-rw-r--r--src/protocol/visitor/tagged.rs28
-rw-r--r--src/protocol/visitor/value.rs42
-rw-r--r--src/protocol/walker/hint.rs25
-rw-r--r--src/walk.rs9
-rw-r--r--src/walk/walkers/core/array.rs19
-rw-r--r--src/walk/walkers/core/bool.rs11
-rw-r--r--tests/demo.rs70
-rw-r--r--tests/hook.rs40
18 files changed, 362 insertions, 237 deletions
diff --git a/src/build.rs b/src/build.rs
index 72f395d..b75fa6b 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -1,12 +1,12 @@
pub mod builders;
use crate::{
- protocol::{AnyTraitSendObj as _, Effect, SyncEffect, Visitor},
+ protocol::{AsObj as _, Effect, EffectAnyTrait, SyncEffect, Visitor, Yield},
Walker,
};
/// A buildable type.
-pub trait Build<'ctx, E: Effect<'ctx>>: Sized {
+pub trait Build<'ctx, E: EffectAnyTrait<'ctx>>: Sized {
/// The builder that can be used to build a value of `Self`.
type Builder: Builder<'ctx, E, Value = Self>;
}
@@ -24,7 +24,9 @@ pub trait Build<'ctx, E: Effect<'ctx>>: Sized {
/// the builder with data from it's walk.
/// - Call [`Self::build()`] to finish building the value and get any errors
/// that happened during filling it with data.
-pub trait Builder<'ctx, E: Effect<'ctx>>: AsVisitor<'ctx, E> {
+pub trait Builder<'ctx, E: EffectAnyTrait<'ctx>>: AsVisitor<'ctx, E> {
+ type Effect: Effect<'ctx, Result<Self::Value, Self::Error>>;
+
type Seed;
/// Error that can happen during filling the builder with data.
@@ -39,21 +41,21 @@ pub trait Builder<'ctx, E: Effect<'ctx>>: AsVisitor<'ctx, E> {
///
/// If an error happened with the builder during the walk
/// it will be reported here.
- fn build(self) -> Result<Self::Value, Self::Error>;
+ fn build<'a>(self) -> Yield<'a, 'ctx, Result<Self::Value, Self::Error>, Self::Effect> where Self: 'a;
}
-pub trait AsVisitor<'ctx, E: Effect<'ctx>> {
+pub trait AsVisitor<'ctx, E: EffectAnyTrait<'ctx>> {
/// Get the builder as a visitor that a walker can use.
///
/// This is expected to just be `self`.
fn as_visitor(&mut self) -> Visitor<'_, 'ctx, E>;
}
-pub trait DefaultBuilder<'ctx, E: Effect<'ctx>>: Builder<'ctx, E> {
+pub trait DefaultBuilder<'ctx, E: EffectAnyTrait<'ctx>>: Builder<'ctx, E> {
fn default() -> Self;
}
-impl<'ctx, B: Builder<'ctx, E>, E: Effect<'ctx>> DefaultBuilder<'ctx, E> for B
+impl<'ctx, B: Builder<'ctx, E>, E: EffectAnyTrait<'ctx>> DefaultBuilder<'ctx, E> for B
where
B::Seed: Default,
{
@@ -68,29 +70,30 @@ pub enum BuildError<B, W> {
Walker(W),
}
-// #[inline]
-// pub fn build<'ctx, T: Build<'ctx, SyncEffect>, W: for<'a> Walker<'a, 'ctx, Effect = SyncEffect>>(
-// walker: W,
-// ) -> Result<
-// T,
-// BuildError<
-// <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Error,
-// W::Error,
-// >,
-// >
-// where
-// <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Seed: Default,
-// {
-// let mut builder = T::Builder::from_seed(Default::default());
-//
-// if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor().as_obj_mut()) {
-// return Err(BuildError::Walker(err));
-// }
-//
-// builder.build().map_err(BuildError::Builder)
-// }
+#[inline]
+pub fn build<'ctx, T: Build<'ctx, SyncEffect>, W: Walker<'ctx, Effect = SyncEffect>>(
+ walker: W,
+) -> Result<
+ T,
+ BuildError<
+ <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Error,
+ W::Error,
+ >,
+>
+where
+ <T as Build<'ctx, SyncEffect>>::Builder: Builder<'ctx, SyncEffect, Effect = SyncEffect>,
+ <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Seed: Default,
+{
+ let mut builder = T::Builder::from_seed(Default::default());
+
+ if let Err(err) = walker.walk(builder.as_visitor().as_obj_mut()) {
+ return Err(BuildError::Walker(err));
+ }
+
+ builder.build().map_err(BuildError::Builder)
+}
-pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect>, W: Walker<'ctx, Effect = SyncEffect>>(
+pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect, Effect = SyncEffect>, W: Walker<'ctx, Effect = SyncEffect>>(
walker: W,
) -> Result<B::Value, BuildError<B::Error, W::Error>>
where
@@ -98,7 +101,7 @@ where
{
let mut builder = B::from_seed(Default::default());
- if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor().as_obj_mut()) {
+ if let Err(err) = walker.walk(builder.as_visitor().as_obj_mut()) {
return Err(BuildError::Walker(err));
}
diff --git a/src/build/builders/core/array.rs b/src/build/builders/core/array.rs
index aca8775..34b8f65 100644
--- a/src/build/builders/core/array.rs
+++ b/src/build/builders/core/array.rs
@@ -4,7 +4,7 @@ use crate::{
any_trait,
protocol::{
visitor::{Sequence, SequenceScope, Status},
- AnyTraitObj, AnyTraitSendObj as _, ControlFlowFor, Effect, SyncEffect,
+ AsObj as _, Yield, Effect, SyncEffect, EffectAnyTrait,
},
AsVisitor, DefaultBuilder,
};
@@ -15,7 +15,7 @@ use crate::protocol::AsyncEffect;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
-impl<'ctx, T, const N: usize, E: Effect<'ctx>> crate::Build<'ctx, E> for [T; N]
+impl<'ctx, T, const N: usize, E: EffectAnyTrait<'ctx>> crate::Build<'ctx, E> for [T; N]
where
T: crate::Build<'ctx, E>,
<T as crate::Build<'ctx, E>>::Builder: DefaultBuilder<'ctx, E>,
@@ -30,15 +30,15 @@ pub enum ArrayError<E> {
Item(usize, E),
}
-pub struct Builder<'ctx, B: crate::Builder<'ctx, E>, const N: usize, E: Effect<'ctx>> {
+pub struct Builder<'ctx, B: crate::Builder<'ctx, E>, const N: usize, E: EffectAnyTrait<'ctx>> {
array: MaybeUninit<[B::Value; N]>,
index: usize,
item_err: Option<(usize, B::Error)>,
_marker: PhantomData<fn() -> E>,
}
-impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'ctx>> crate::Builder<'ctx, E>
- for Builder<'ctx, B, N, E>
+impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: EffectAnyTrait<'ctx>>
+ crate::Builder<'ctx, E> for Builder<'ctx, B, N, E>
where
Self: AsVisitor<'ctx, E>,
{
@@ -46,7 +46,7 @@ where
type Value = [B::Value; N];
- fn build(self) -> Result<Self::Value, Self::Error> {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
if let Some((index, err)) = self.item_err {
return Err(ArrayError::Item(index, err));
}
@@ -68,21 +68,25 @@ where
_marker: PhantomData,
}
}
+
+ type Effect = SyncEffect;
}
impl<'ctx, B: crate::DefaultBuilder<'ctx, SyncEffect>, const N: usize> AsVisitor<'ctx, SyncEffect>
for Builder<'ctx, B, N, SyncEffect>
+where
+ B: crate::Builder<'ctx, SyncEffect, Effect = SyncEffect>
{
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
- AnyTraitObj::from_obj(self)
+ self
}
}
// #[cfg(not(feature = "alloc"))]
any_trait! {
- impl['a, 'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'ctx>] Builder<'ctx, B, N, E> = [
- dyn Sequence<'ctx> + 'a,
- ]
+ impl['a, 'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'ctx, ControlFlow<(), ()>>] Builder<'ctx, B, N, E> = [
+ dyn Sequence<'ctx, SyncEffect> + 'a,
+ ] where B: crate::Builder<'ctx, E, Effect = SyncEffect>
}
// #[cfg(feature = "alloc")]
@@ -93,11 +97,16 @@ any_trait! {
// ]
// }
-impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'ctx>> Sequence<'ctx>
+impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: EffectAnyTrait<'ctx>> Sequence<'ctx, SyncEffect>
for Builder<'ctx, B, N, E>
+where
+ B: crate::Builder<'ctx, E, Effect = SyncEffect>
{
#[inline]
- fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a {
+ fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
loop {
// Check if the array is full.
if self.index >= N {
diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs
index 19fee66..c9c0be9 100644
--- a/src/build/builders/core/bool.rs
+++ b/src/build/builders/core/bool.rs
@@ -3,14 +3,11 @@ use core::{marker::PhantomData, ops::ControlFlow};
use crate::{
any::static_wrapper::OwnedStatic,
any_trait,
- protocol::{
- visitor::Value, AnyTraitObj, AnyTraitSendObj, AsyncEffect, ControlFlowFor, Effect,
- SyncEffect,
- },
+ protocol::{visitor::Value, AsObj, AsyncEffect, Yield, Effect, SyncEffect},
AsVisitor,
};
-impl<'ctx, E: Effect<'ctx>> crate::Build<'ctx, E> for bool
+impl<'ctx, E: Effect<'ctx, ControlFlow<(), ()>>> crate::Build<'ctx, E> for bool
where
Builder<E>: AsVisitor<'ctx, E>,
{
@@ -24,7 +21,7 @@ pub enum Error {
pub struct Builder<E>(Option<bool>, PhantomData<fn() -> E>);
-impl<'ctx, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<E>
+impl<'ctx, E: Effect<'ctx, ControlFlow<(), ()>>> crate::Builder<'ctx, E> for Builder<E>
where
Self: AsVisitor<'ctx, E>,
{
@@ -33,38 +30,43 @@ where
type Value = bool;
#[inline]
- fn build(self) -> Result<Self::Value, Self::Error> {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
self.0.ok_or(Error::Incomplete)
}
type Seed = ();
- fn from_seed(seed: Self::Seed) -> Self {
+ fn from_seed(_seed: Self::Seed) -> Self {
Self(None, PhantomData)
}
+
+ type Effect = SyncEffect;
}
impl<'ctx> AsVisitor<'ctx, SyncEffect> for Builder<SyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
- AnyTraitObj::from_obj(self)
+ self
}
}
impl<'ctx> AsVisitor<'ctx, AsyncEffect> for Builder<AsyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
- AnyTraitSendObj::from_obj_send(self)
+ self
}
}
any_trait! {
impl['a, 'ctx, E] Builder<E> = [
- dyn Value<'ctx, OwnedStatic<bool>> + 'a,
+ dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
]
}
-impl<'ctx, E> Value<'ctx, OwnedStatic<bool>> for Builder<E> {
+impl<'ctx, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<E> {
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx>where 'ctx: 'a {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
self.0 = Some(value);
ControlFlow::Continue(())
}
diff --git a/src/build/builders/serde/deserialize.rs b/src/build/builders/serde/deserialize.rs
index 2fbc1c0..8a9fa3e 100644
--- a/src/build/builders/serde/deserialize.rs
+++ b/src/build/builders/serde/deserialize.rs
@@ -9,7 +9,7 @@ use crate::{
any_trait,
protocol::{
visitor::{Sequence, SequenceScope, Status, Value},
- AnyTraitObj, AnyTraitSendObj, AsyncEffect, ControlFlowFor, Effect, SyncEffect,
+ AsObj, AsyncEffect, Yield, Effect, SyncEffect,
},
AsVisitor, Builder as _,
};
@@ -25,7 +25,7 @@ impl std::error::Error for Error {}
pub struct Builder<T, E>(Result<T, Error>, PhantomData<fn() -> E>);
-impl<'ctx, T: Deserialize<'ctx>, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<T, E>
+impl<'ctx, T: Deserialize<'ctx>, E: Effect<'ctx, ControlFlow<(), ()>>> crate::Builder<'ctx, E> for Builder<T, E>
where
Self: AsVisitor<'ctx, E>,
{
@@ -33,7 +33,7 @@ where
type Value = T;
- fn build(self) -> Result<Self::Value, Self::Error> {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
self.0
}
@@ -42,35 +42,40 @@ where
fn from_seed(seed: Self::Seed) -> Self {
Self(Err(Error::Incomplete), PhantomData)
}
+
+ type Effect = SyncEffect;
}
impl<'ctx, T: Deserialize<'ctx>> AsVisitor<'ctx, SyncEffect> for Builder<T, SyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
- AnyTraitObj::from_obj(self)
+ self
}
}
impl<'ctx, T: Deserialize<'ctx> + Send> AsVisitor<'ctx, AsyncEffect> for Builder<T, AsyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
- AnyTraitSendObj::from_obj_send(self)
+ self
}
}
any_trait! {
impl['a, 'ctx, T: Deserialize<'ctx>, E] Builder<T, E> = [
- dyn Value<'ctx, OwnedStatic<bool>> + 'a,
- dyn Sequence<'ctx> + 'a,
+ dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
+ dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
enum InjectedValue<'a, 'ctx> {
Bool(bool),
- Sequence(&'a mut dyn SequenceScope<'ctx>),
+ Sequence(&'a mut dyn SequenceScope<'ctx, SyncEffect>),
}
-impl<'ctx, T: Deserialize<'ctx>, E> Value<'ctx, OwnedStatic<bool>> for Builder<T, E> {
+impl<'ctx, T: Deserialize<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<T, E> {
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
self.0 = T::deserialize(InjectedValue::Bool(value));
if self.0.is_err() {
@@ -81,9 +86,12 @@ impl<'ctx, T: Deserialize<'ctx>, E> Value<'ctx, OwnedStatic<bool>> for Builder<T
}
}
-impl<'ctx, T: Deserialize<'ctx>, E> Sequence<'ctx> for Builder<T, E> {
+impl<'ctx, T: Deserialize<'ctx>, E> Sequence<'ctx, SyncEffect> for Builder<T, E> {
#[inline]
- fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a {
+ fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
self.0 = T::deserialize(InjectedValue::Sequence(scope));
if self.0.is_err() {
@@ -130,7 +138,7 @@ impl<'a, 'ctx> Deserializer<'ctx> for InjectedValue<'a, 'ctx> {
}
}
-struct SequenceAccess<'a, 'ctx>(&'a mut dyn SequenceScope<'ctx>);
+struct SequenceAccess<'a, 'ctx>(&'a mut dyn SequenceScope<'ctx, SyncEffect>);
impl<'a, 'ctx> SeqAccess<'ctx> for SequenceAccess<'a, 'ctx> {
type Error = Error;
diff --git a/src/build/builders/serde/deserialize_seed.rs b/src/build/builders/serde/deserialize_seed.rs
index df38405..23434cf 100644
--- a/src/build/builders/serde/deserialize_seed.rs
+++ b/src/build/builders/serde/deserialize_seed.rs
@@ -12,7 +12,7 @@ use crate::{
any_trait,
protocol::{
visitor::{Sequence, SequenceScope, Status, Value},
- AnyTraitObj, AnyTraitSendObj, AsyncEffect, ControlFlowFor, Effect, SyncEffect,
+ AsObj, AsyncEffect, Yield, Effect, SyncEffect,
},
AsVisitor, Builder as _,
};
@@ -41,15 +41,17 @@ pub struct Builder<'ctx, T: DeserializeSeed<'ctx>, E>(
PhantomData<fn() -> E>,
);
-impl<'ctx, T: DeserializeSeed<'ctx>, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<'ctx, T, E>
+impl<'ctx, T: DeserializeSeed<'ctx>, E: Effect<'ctx, ControlFlow<(), ()>>> crate::Builder<'ctx, E>
+ for Builder<'ctx, T, E>
where
Self: AsVisitor<'ctx, E>,
{
+
type Error = Error<T>;
type Value = T::Value;
- fn build(self) -> Result<Self::Value, Self::Error> {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
self.0
}
@@ -58,11 +60,13 @@ where
fn from_seed(seed: Self::Seed) -> Self {
Self(Err(Error::Pending(seed)), PhantomData)
}
+
+ type Effect = SyncEffect;
}
impl<'ctx, T: DeserializeSeed<'ctx>> AsVisitor<'ctx, SyncEffect> for Builder<'ctx, T, SyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
- AnyTraitObj::from_obj(self)
+ self
}
}
@@ -72,26 +76,32 @@ where
T::Value: Send,
{
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
- AnyTraitSendObj::from_obj_send(self)
+ self
}
}
any_trait! {
impl['a, 'ctx, T: DeserializeSeed<'ctx>, E] Builder<'ctx, T, E> = [
- dyn Value<'ctx, OwnedStatic<bool>> + 'a,
- dyn Sequence<'ctx> + 'a,
+ dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
+ dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
enum InjectedValue<'a, 'ctx, T> {
Bool(bool),
- Sequence(&'a mut dyn SequenceScope<'ctx>),
+ Sequence(&'a mut dyn SequenceScope<'ctx, SyncEffect>),
Extra(PhantomData<T>),
}
-impl<'ctx, T: DeserializeSeed<'ctx>, E> Value<'ctx, OwnedStatic<bool>> for Builder<'ctx, T, E> {
+impl<'ctx, T: DeserializeSeed<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<'ctx, T, E> {
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(bool_value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a {
+ fn visit<'a>(
+ &'a mut self,
+ OwnedStatic(bool_value): OwnedStatic<bool>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
let pending = core::mem::replace(&mut self.0, Err(Error::Incomplete));
let Err(Error::Pending(value)) = pending else {
todo!()
@@ -107,9 +117,12 @@ impl<'ctx, T: DeserializeSeed<'ctx>, E> Value<'ctx, OwnedStatic<bool>> for Build
}
}
-impl<'ctx, T: DeserializeSeed<'ctx>, E> Sequence<'ctx> for Builder<'ctx, T, E> {
+impl<'ctx, T: DeserializeSeed<'ctx>, E> Sequence<'ctx, SyncEffect> for Builder<'ctx, T, E> {
#[inline]
- fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a {
+ fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
let pending = core::mem::replace(&mut self.0, Err(Error::Incomplete));
let Err(Error::Pending(value)) = pending else {
todo!()
@@ -162,7 +175,7 @@ impl<'a, 'ctx, T> Deserializer<'ctx> for InjectedValue<'a, 'ctx, T> {
}
}
-struct SequenceAccess<'a, 'ctx, T>(&'a mut dyn SequenceScope<'ctx>, PhantomData<T>);
+struct SequenceAccess<'a, 'ctx, T>(&'a mut dyn SequenceScope<'ctx, SyncEffect>, PhantomData<T>);
impl<'a, 'ctx, T> SeqAccess<'ctx> for SequenceAccess<'a, 'ctx, T> {
type Error = Error<T>;
diff --git a/src/hkt.rs b/src/hkt.rs
index d41a7ae..8a7a48c 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -14,9 +14,9 @@ macro_rules! type_class {
pub trait Hkt<$ctx>: for<$lt> ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx>> {}
- impl<$ctx, T> Hkt<$ctx> for T
- where
- T: for<$lt> ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx>>
+ impl<$ctx, T> Hkt<$ctx> for T
+ where
+ T: for<$lt> ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx>>
{}
pub type T<$lt, $ctx, H> = <H as ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx>>>::T;
@@ -32,14 +32,14 @@ pub use type_class;
macro_rules! hkt {
(
($($type_class:tt)*):
- for<$lt:lifetime, $ctx:lifetime>
+ for<$lt:lifetime, $ctx:lifetime>
$vis:vis $name:ident$([$($generic:tt)*])?
$(where {$($bound:tt)*})? => $($type:tt)*
) => {
$vis struct $name<$ctx $(, $($generic)*)?>(core::marker::PhantomData<fn() -> (&$ctx (), $($($generic)*)?)>);
- impl<$lt, $ctx $(, $($generic)*)?> $($type_class)*::ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx>> for $name<$ctx $(, $($generic)*)?>
- $(where $($bound)*)?
+ impl<$lt, $ctx $(, $($generic)*)?> $($type_class)*::ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx>> for $name<$ctx $(, $($generic)*)?>
+ $(where $($bound)*)?
{
type T = $($type)*;
}
diff --git a/src/lib.rs b/src/lib.rs
index 61c44d1..f175c63 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,9 +9,9 @@ extern crate alloc;
pub mod any;
mod build;
+pub mod hkt;
pub mod protocol;
pub mod symbol;
-pub mod hkt;
mod walk;
// pub mod impls;
diff --git a/src/protocol.rs b/src/protocol.rs
index 7ff6988..4ad6d8d 100644
--- a/src/protocol.rs
+++ b/src/protocol.rs
@@ -35,14 +35,14 @@
use core::{
future::Future,
+ marker::PhantomData,
pin::{pin, Pin},
ptr,
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
- marker::PhantomData,
};
use crate::any::AnyTrait;
-use crate::hkt::{type_class, hkt};
+use crate::hkt::{hkt, type_class};
pub mod visitor;
pub mod walker;
@@ -50,25 +50,18 @@ pub mod walker;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
-pub type Visitor<'a, 'ctx, Effect> = any_trait_send_obj::T<'a, 'ctx, <Effect as self::Effect<'ctx>>::VisitorHkt>;
-pub type Walker<'a, 'ctx, Effect> = any_trait_send_obj::T<'a, 'ctx, <Effect as self::Effect<'ctx>>::WalkerHkt>;
-
-pub trait AnyTraitObj<'a, 'ctx: 'a>: AnyTraitSendObj<'a, 'ctx> {
- fn from_obj(value: &'a mut (dyn AnyTrait<'ctx> + 'a)) -> Self;
-}
+pub type Visitor<'a, 'ctx, Effect> =
+ as_obj::T<'a, 'ctx, <Effect as self::EffectAnyTrait<'ctx>>::AnyTrait>;
+pub type Walker<'a, 'ctx, Effect> =
+ as_obj::T<'a, 'ctx, <Effect as self::EffectAnyTrait<'ctx>>::AnyTrait>;
-pub trait AnyTraitSendObj<'a, 'ctx: 'a> {
- fn from_obj_send(value: &'a mut (dyn AnyTrait<'ctx> + Send + 'a)) -> Self;
+pub trait AsObj<'a, 'ctx: 'a> {
fn as_obj(&self) -> &dyn AnyTrait<'ctx>;
fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx>;
fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx>;
}
-impl<'a, 'ctx: 'a> AnyTraitSendObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) {
- fn from_obj_send(value: &'a mut (dyn AnyTrait<'ctx> + Send + 'a)) -> Self {
- value
- }
-
+impl<'a, 'ctx: 'a> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) {
fn as_obj(&self) -> &dyn AnyTrait<'ctx> {
*self
}
@@ -82,11 +75,7 @@ impl<'a, 'ctx: 'a> AnyTraitSendObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + '
}
}
-impl<'a, 'ctx: 'a> AnyTraitSendObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + Send + 'a) {
- fn from_obj_send(value: &'a mut (dyn AnyTrait<'ctx> + Send + 'a)) -> Self {
- value
- }
-
+impl<'a, 'ctx: 'a> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + Send + 'a) {
fn as_obj(&self) -> &dyn AnyTrait<'ctx> {
*self
}
@@ -100,43 +89,65 @@ impl<'a, 'ctx: 'a> AnyTraitSendObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + S
}
}
-impl<'a, 'ctx: 'a> AnyTraitObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) {
- fn from_obj(value: &'a mut (dyn AnyTrait<'ctx> + 'a)) -> Self {
- value
- }
-}
-
-type_class!(for<'lt, 'ctx> pub any_trait_send_obj: AnyTraitSendObj<'lt, 'ctx>);
+type_class!(for<'lt, 'ctx> pub as_obj: AsObj<'lt, 'ctx>);
type_class!(for<'lt, 'ctx> pub any_t);
-pub trait Effect<'ctx, C = (), B = ()>: 'static {
- type VisitorHkt: any_trait_send_obj::Hkt<'ctx>;
- type WalkerHkt: any_trait_send_obj::Hkt<'ctx>;
- type ControlFlowHkt: any_t::Hkt<'ctx>;
+pub trait EffectAnyTrait<'ctx>: 'static {
+ /// The `dyn AnyTrait<'ctx>` for the effect.
+ ///
+ /// this allows adding extra bounds to the trait object.
+ type AnyTrait: as_obj::Hkt<'ctx>;
}
-pub type ControlFlowFor<'a, 'ctx, E = SyncEffect, C = (), B = ()> =
- any_t::T<'a, 'ctx, <E as Effect<'ctx, C, B>>::ControlFlowHkt>;
+/// Trait for effects.
+pub trait Effect<'ctx, T>: EffectAnyTrait<'ctx> {
+ /// The type functions return for this effect.
+ ///
+ /// This type should resolve into a `T`.
+ type Yield: any_t::Hkt<'ctx>;
+}
+
+pub type Yield<'a, 'ctx, T, E> = any_t::T<'a, 'ctx, <E as Effect<'ctx, T>>::Yield>;
pub enum SyncEffect {}
-hkt!((any_trait_send_obj): for<'a, 'ctx> pub AnyTraitSendObjHkt => &'a mut (dyn AnyTrait<'ctx> + Send + 'a));
-hkt!((any_trait_send_obj): for<'a, 'ctx> pub AnyTraitObjHkt => &'a mut (dyn AnyTrait<'ctx> + 'a));
+hkt!((as_obj): for<'a, 'ctx> pub AnyTraitSendObj => &'a mut (dyn AnyTrait<'ctx> + Send + 'a));
+hkt!((as_obj): for<'a, 'ctx> pub AnyTraitObj => &'a mut (dyn AnyTrait<'ctx> + 'a));
-hkt!((any_t): for<'a, 'ctx> pub SyncControlFlowHkt[C, B] => core::ops::ControlFlow<B, C>);
+hkt!((any_t): for<'a, 'ctx> pub SyncYield[T] => T);
-impl<'ctx, C, B> Effect<'ctx, C, B> for SyncEffect {
- type ControlFlowHkt = SyncControlFlowHkt<'ctx, C, B>;
+impl<'ctx, T> Effect<'ctx, T> for SyncEffect {
+ type Yield = SyncYield<'ctx, T>;
+}
- type VisitorHkt = AnyTraitObjHkt<'ctx>;
+impl<'ctx> EffectAnyTrait<'ctx> for SyncEffect {
+ type AnyTrait = AnyTraitObj<'ctx>;
+}
- type WalkerHkt = AnyTraitObjHkt<'ctx>;
+#[cfg(feature = "alloc")]
+hkt!((any_t): for<'a, 'ctx> pub AsyncSendYield[T] =>
+ core::pin::Pin<
+ Box<dyn core::future::Future<Output = T> + Send + 'a>,
+ >
+);
+
+#[cfg(feature = "alloc")]
+pub enum AsyncSendEffect {}
+
+#[cfg(feature = "alloc")]
+impl<'ctx, T> Effect<'ctx, T> for AsyncSendEffect {
+ type Yield = AsyncSendYield<'ctx, T>;
+}
+
+#[cfg(feature = "alloc")]
+impl<'ctx> EffectAnyTrait<'ctx> for AsyncSendEffect {
+ type AnyTrait = AnyTraitSendObj<'ctx>;
}
#[cfg(feature = "alloc")]
-hkt!((any_t): for<'a, 'ctx> pub AsyncControlFlowHkt[C, B] =>
+hkt!((any_t): for<'a, 'ctx> pub AsyncYield[T] =>
core::pin::Pin<
- Box<dyn core::future::Future<Output = core::ops::ControlFlow<B, C>> + Send + 'a>,
+ Box<dyn core::future::Future<Output = T> + 'a>,
>
);
@@ -144,8 +155,11 @@ hkt!((any_t): for<'a, 'ctx> pub AsyncControlFlowHkt[C, B] =>
pub enum AsyncEffect {}
#[cfg(feature = "alloc")]
-impl<'ctx, C, B> Effect<'ctx, C, B> for AsyncEffect {
- type VisitorHkt = AnyTraitSendObjHkt<'ctx>;
- type WalkerHkt = AnyTraitSendObjHkt<'ctx>;
- type ControlFlowHkt = AsyncControlFlowHkt<'ctx, C, B>;
+impl<'ctx, T> Effect<'ctx, T> for AsyncEffect {
+ type Yield = AsyncYield<'ctx, T>;
+}
+
+#[cfg(feature = "alloc")]
+impl<'ctx> EffectAnyTrait<'ctx> for AsyncEffect {
+ type AnyTrait = AnyTraitObj<'ctx>;
}
diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs
index bf0ba98..d79ef73 100644
--- a/src/protocol/visitor/request_hint.rs
+++ b/src/protocol/visitor/request_hint.rs
@@ -1,21 +1,23 @@
+use core::ops::ControlFlow;
+
use crate::{
nameable,
- protocol::{ControlFlowFor, Effect, SyncEffect, Walker},
+ protocol::{Yield, Effect, SyncEffect, Walker},
};
/// Protocol for requesting a hint from a visitor.
-pub trait RequestHint<'a, 'ctx: 'a, E: Effect<'ctx> = SyncEffect> {
+pub trait RequestHint<'a, 'ctx: 'a, E: Effect<'ctx, ControlFlow<(), ()>>> {
/// Call this to request a hint.
///
/// `walker` is what the visitor (`self`) will call to give a hint using the
/// [`Hint`][crate::builtins::walker::Hint] protocol.
- fn request_hint(&'a mut self, walker: Walker<'a, 'ctx, E>) -> ControlFlowFor<'a, 'ctx, E>;
+ fn request_hint(&'a mut self, walker: Walker<'a, 'ctx, E>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>;
}
nameable! {
pub struct Name['a, 'ctx, E];
impl [E] for dyn RequestHint<'a, 'ctx, E> + 'a where {
- E: Effect<'ctx>,
+ E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a
}
}
diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs
index 47ea03e..d345ed1 100644
--- a/src/protocol/visitor/sequence.rs
+++ b/src/protocol/visitor/sequence.rs
@@ -1,35 +1,41 @@
+use core::ops::ControlFlow;
+
use crate::{
+ hkt::hkt,
nameable,
- protocol::{walker::HintMeta, ControlFlowFor, Effect, SyncEffect, Visitor, any_t},
- hkt::hkt
+ protocol::{any_t, walker::HintMeta, Yield, Effect, SyncEffect, Visitor},
};
-pub trait Sequence<'ctx, E: Effect<'ctx> = SyncEffect> {
+pub trait Sequence<'ctx, E: Effect<'ctx, ControlFlow<(), ()>>> {
fn visit<'a>(
&'a mut self,
scope: &'a mut dyn SequenceScope<'ctx, E>,
- ) -> ControlFlowFor<'a, 'ctx, E> where 'ctx: 'a;
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ where
+ 'ctx: 'a;
}
nameable! {
pub struct Name['a, 'ctx, E];
impl [E] for dyn Sequence<'ctx, E> + 'a where {
- E: Effect<'ctx> + Effect<'ctx, Status>,
+ E: Effect<'ctx, ControlFlow<(), ()>> + Effect<'ctx, ControlFlow<(), Status>>,
'ctx: 'a
}
impl [E] where dyn Sequence<'ctx, E> + 'a {
- E: Effect<'ctx> + Effect<'ctx, Status>,
+ E: Effect<'ctx, ControlFlow<(), ()>> + Effect<'ctx, ControlFlow<(), Status>>,
'ctx: 'a
}
}
-pub trait SequenceScope<'ctx, E = SyncEffect>
+pub trait SequenceScope<'ctx, E>
where
- E: Effect<'ctx> + Effect<'ctx, Status>,
+ E: Effect<'ctx, ControlFlow<(), Status>>,
{
- fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> ControlFlowFor<'a, 'ctx, E, Status> where 'ctx: 'a;
+ fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> Yield<'a, 'ctx, ControlFlow<(), Status>, E>
+ where
+ 'ctx: 'a;
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
@@ -49,8 +55,8 @@ pub struct Hint {
pub len: (usize, Option<usize>),
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx>> HintMeta<'ctx> for dyn Sequence<'ctx, E> + '_ {
- type KnownHkt = KnownHkt<'ctx>;
+impl<'a, 'ctx: 'a, E: Effect<'ctx, ControlFlow<(), ()>>> HintMeta<'ctx> for dyn Sequence<'ctx, E> + '_ {
+ type Known = KnownHkt<'ctx>;
type Hint = Hint;
}
diff --git a/src/protocol/visitor/tagged.rs b/src/protocol/visitor/tagged.rs
index 1f33ca7..0bc90a0 100644
--- a/src/protocol/visitor/tagged.rs
+++ b/src/protocol/visitor/tagged.rs
@@ -1,37 +1,45 @@
+use core::ops::ControlFlow;
+
use crate::{
+ hkt::hkt,
nameable,
- protocol::{walker::HintMeta, ControlFlowFor, Effect, SyncEffect, Visitor, any_t},
+ protocol::{any_t, walker::HintMeta, Yield, Effect, SyncEffect, Visitor},
symbol::Symbol,
- hkt::hkt,
};
-pub trait Tagged<'ctx, E: Effect<'ctx> = SyncEffect> {
+pub trait Tagged<'ctx, E: Effect<'ctx, ControlFlow<(), ()>>> {
fn visit<'a>(
&'a mut self,
scope: &'a mut dyn TaggedScope<'ctx, E>,
- ) -> ControlFlowFor<'a, 'ctx, E> where 'ctx: 'a;
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ where
+ 'ctx: 'a;
}
nameable! {
pub struct Name['a, 'ctx, E];
impl [E] for dyn Tagged<'ctx, E> + 'a where {
- E: Effect<'ctx>,
+ E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a
}
impl [E] where dyn Tagged<'ctx, E> + 'a {
- E: Effect<'ctx>,
+ E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a
}
}
-pub trait TaggedScope<'ctx, E: Effect<'ctx> = SyncEffect> {
+pub trait TaggedScope<'ctx, E: Effect<'ctx, ControlFlow<(), ()>>> {
fn kind(&mut self) -> Symbol;
- fn tag<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> ControlFlowFor<'a, 'ctx, E> where 'ctx: 'a;
+ fn tag<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ where
+ 'ctx: 'a;
- fn value<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> ControlFlowFor<'a, 'ctx, E> where 'ctx: 'a;
+ fn value<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ where
+ 'ctx: 'a;
}
hkt!((any_t): for<'a, 'ctx> pub KnownHkt => Known);
@@ -45,7 +53,7 @@ pub struct Hint {
}
impl<'a, 'ctx: 'a, Return> HintMeta<'ctx> for dyn Tagged<'ctx, Return> + 'a {
- type KnownHkt = KnownHkt<'ctx>;
+ type Known = KnownHkt<'ctx>;
type Hint = Hint;
}
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index 20438bb..ed3a0bd 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -2,17 +2,19 @@
//!
//! In some sense, this is the most basic protocol.
+use core::ops::ControlFlow;
+
use crate::{
any::{TypeName, TypeNameable},
- nameable,
- protocol::{walker::HintMeta, ControlFlowFor, Effect, SyncEffect, any_t},
hkt::hkt,
+ nameable,
+ protocol::{any_t, walker::HintMeta, Effect, SyncEffect, Yield},
};
/// Trait object for the [`Value`] protocol.
///
/// Types implementing the [`Value`] protocol will implement this trait.
-pub trait Value<'ctx, T, E: Effect<'ctx> = SyncEffect> {
+pub trait Value<'ctx, T, E: Effect<'ctx, ControlFlow<(), ()>>> {
/// Visit a value of type `T`.
///
/// Use this to give a value to a visitor. Its expected that a walker
@@ -22,7 +24,9 @@ pub trait Value<'ctx, T, E: Effect<'ctx> = SyncEffect> {
/// If a [`ControlFlow::Break`] is returned then the walker
/// should stop walking as soon as possible as there has likely been
/// and error.
- fn visit<'a>(&'a mut self, value: T) -> ControlFlowFor<'a, 'ctx, E> where 'ctx: 'a;
+ fn visit<'a>(&'a mut self, value: T) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ where
+ 'ctx: 'a;
}
nameable! {
@@ -30,13 +34,13 @@ nameable! {
impl [T::Name, E] for dyn Value<'ctx, T, E> + 'a where {
T: TypeNameable<'a, 'ctx> + ?Sized,
- E: Effect<'ctx>,
+ E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a,
}
impl [T, E] where dyn Value<'ctx, T::Nameable, E> + 'a {
T: TypeName<'a, 'ctx> + ?Sized,
- E: Effect<'ctx>,
+ E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a,
}
}
@@ -44,8 +48,10 @@ nameable! {
hkt!((any_t): for<'a, 'ctx> pub KnownHkt => ());
// This enrolls the Value protocol into the walker hint system.
-impl<'a, 'ctx: 'a, T, E: Effect<'ctx>> HintMeta<'ctx> for dyn Value<'ctx, T, E> + 'a {
- type KnownHkt = KnownHkt<'ctx>;
+impl<'a, 'ctx: 'a, T, E: Effect<'ctx, ControlFlow<(), ()>>> HintMeta<'ctx>
+ for dyn Value<'ctx, T, E> + 'a
+{
+ type Known = KnownHkt<'ctx>;
type Hint = ();
}
@@ -72,7 +78,10 @@ mod test {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<i32>,
- ) -> core::ops::ControlFlow<()> where 'ctx: 'a {
+ ) -> core::ops::ControlFlow<()>
+ where
+ 'ctx: 'a,
+ {
self.0 = Some(value);
ControlFlow::Continue(())
}
@@ -82,7 +91,10 @@ mod test {
fn visit<'a>(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, i32>,
- ) -> core::ops::ControlFlow<()> where 'ctx: 'a {
+ ) -> core::ops::ControlFlow<()>
+ where
+ 'ctx: 'a,
+ {
self.0 = Some(*value);
ControlFlow::Continue(())
}
@@ -121,7 +133,10 @@ mod test {
fn visit<'a>(
&'a mut self,
BorrowedMutStatic(value): BorrowedMutStatic<'ctx, String>,
- ) -> ControlFlow<()> where 'ctx: 'a {
+ ) -> ControlFlow<()>
+ where
+ 'ctx: 'a,
+ {
self.0 = Some(value);
ControlFlow::Continue(())
}
@@ -154,7 +169,10 @@ mod test {
fn visit<'a>(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, str>,
- ) -> ControlFlow<()> where 'ctx: 'a {
+ ) -> ControlFlow<()>
+ where
+ 'ctx: 'a,
+ {
self.0 = Some(value);
ControlFlow::Continue(())
}
diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs
index ce73b7e..56d5793 100644
--- a/src/protocol/walker/hint.rs
+++ b/src/protocol/walker/hint.rs
@@ -4,10 +4,12 @@
//! this module gives a protocol by which a visitor can give a hint
//! to the walker about what it is expecting.
+use core::ops::ControlFlow;
+
use crate::{
any::{TypeName, TypeNameable},
nameable,
- protocol::{ControlFlowFor, Effect, SyncEffect, Visitor, any_t},
+ protocol::{any_t, Effect, EffectAnyTrait, SyncEffect, Visitor, Yield},
};
/// Meta information for the hint.
@@ -18,16 +20,19 @@ pub trait HintMeta<'ctx> {
///
/// This should be information easy to get without changing the state of the walker
/// in an irreversible way.
- type KnownHkt: any_t::Hkt<'ctx>;
+ type Known: any_t::Hkt<'ctx>;
/// Extra information the visitor can give to the walker about what it is expecting.
type Hint;
}
+pub type Known<'a, 'ctx, Protocol> = any_t::T<'a, 'ctx, <Protocol as HintMeta<'ctx>>::Known>;
+
/// Object implementing the [`Hint`] protocol.
-pub trait Hint<'ctx, Protocol: ?Sized + HintMeta<'ctx>, E = SyncEffect>
+pub trait Hint<'ctx, Protocol: ?Sized + HintMeta<'ctx>, E>
where
- E: Effect<'ctx> + for<'a> Effect<'ctx, <<Protocol as HintMeta<'ctx>>::KnownHkt as any_t::ForLt<'a, 'ctx, crate::hkt::Bound<'a, 'ctx>>>::T>
+ for<'a> E: Effect<'ctx, ControlFlow<(), ()>>
+ + Effect<'ctx, ControlFlow<(), Known<'a, 'ctx, Protocol>>>,
{
/// Hint to the walker to use the `P` protocol.
///
@@ -36,13 +41,13 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx, E>,
hint: <Protocol as HintMeta<'ctx>>::Hint,
- ) -> ControlFlowFor<'a, 'ctx, E>;
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>;
/// Ask the walker for information about it's support of the protocol.
fn known<'a>(
&'a mut self,
hint: &'a <Protocol as HintMeta<'ctx>>::Hint,
- ) -> ControlFlowFor<'a, 'ctx, E, any_t::T<'a, 'ctx, <Protocol as HintMeta<'ctx>>::KnownHkt>>
+ ) -> Yield<'a, 'ctx, ControlFlow<(), Known<'a, 'ctx, Protocol>>, E>
where
'ctx: 'a;
}
@@ -52,13 +57,13 @@ nameable! {
impl [Protocol::Name, E] for dyn Hint<'ctx, Protocol, E> + 'a where {
Protocol: TypeNameable<'a, 'ctx> + ?Sized,
- E: Effect<'ctx>,
+ E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a,
}
impl [Protocol, E] where dyn Hint<'ctx, Protocol::Nameable, E> + 'a {
Protocol: TypeName<'a, 'ctx> + ?Sized,
- E: Effect<'ctx>,
+ E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a,
}
}
@@ -94,7 +99,7 @@ mod test {
fn known<'a>(
&'a mut self,
hint: &'a <Y as HintMeta<'ctx>>::Hint,
- ) -> ControlFlow<(), any_t::T<'a, 'ctx, <Y as HintMeta<'ctx>>::KnownHkt>>
+ ) -> ControlFlow<(), Known<'a, 'ctx, SyncEffect>>
where
'ctx: 'a,
{
@@ -105,7 +110,7 @@ mod test {
hkt!((any_t): for<'a, 'ctx> KnownHkt => ());
impl<'ctx> HintMeta<'ctx> for Y {
- type KnownHkt = KnownHkt<'ctx>;
+ type Known = KnownHkt<'ctx>;
type Hint = ();
}
diff --git a/src/walk.rs b/src/walk.rs
index fa8ec4b..384760a 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -1,6 +1,6 @@
pub mod walkers;
-use crate::protocol::{ControlFlowFor, Effect, Visitor};
+use crate::protocol::{Effect, EffectAnyTrait, Visitor, Yield};
/// A type that can be walked.
pub trait Walk<'ctx>: Sized {
@@ -22,7 +22,7 @@ pub fn into_walker<'ctx, T: Walk<'ctx>>(value: T) -> T::Walker {
/// - Call [Self::walk()] to walk the value. Data will be sent to the provided
/// visitor.
pub trait Walker<'ctx> {
- type Effect: Effect<'ctx, Self::Output, Self::Error> + Effect<'ctx>;
+ type Effect: Effect<'ctx, Result<Self::Output, Self::Error>>;
type Error;
@@ -38,5 +38,8 @@ pub trait Walker<'ctx> {
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx, Self::Effect>,
- ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error> where Self: 'a, 'ctx: 'a;
+ ) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, Self::Effect>
+ where
+ Self: 'a,
+ 'ctx: 'a;
}
diff --git a/src/walk/walkers/core/array.rs b/src/walk/walkers/core/array.rs
index 33322db..4154e50 100644
--- a/src/walk/walkers/core/array.rs
+++ b/src/walk/walkers/core/array.rs
@@ -6,7 +6,7 @@ use crate::{
protocol::{
visitor::{RequestHint, Sequence, SequenceScope, Status},
walker::{Hint, HintMeta},
- ControlFlowFor, SyncEffect, Visitor,
+ Yield, SyncEffect, Visitor,
},
};
@@ -54,7 +54,7 @@ impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From
fn walk<'a>(
mut self,
visitor: Visitor<'a, 'ctx, Self::Effect>,
- ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error>
+ ) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, Self::Effect>
where
Self: 'a,
{
@@ -63,21 +63,24 @@ impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From
}
if let Some((index, error)) = self.item_err {
- ControlFlow::Break(WalkerError { index, error })
+ Err(WalkerError { index, error })
} else {
- ControlFlow::Continue(())
+ Ok(())
}
}
}
impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From<T>>
- SequenceScope<'ctx> for Walker<'ctx, T, N, W>
+ SequenceScope<'ctx, SyncEffect> for Walker<'ctx, T, N, W>
{
#[inline]
fn next<'a>(
&'a mut self,
visitor: Visitor<'a, 'ctx, SyncEffect>,
- ) -> ControlFlowFor<'a, 'ctx, W::Effect, Status> where 'ctx: 'a {
+ ) -> Yield<'a, 'ctx, ControlFlow<(), Status>, W::Effect>
+ where
+ 'ctx: 'a,
+ {
if self.index >= N {
return ControlFlow::Continue(Status::Done);
}
@@ -93,8 +96,8 @@ impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From
let walker = W::from(value);
match walker.walk(visitor) {
- ControlFlow::Continue(_) => ControlFlow::Continue(Status::Continue),
- ControlFlow::Break(err) => {
+ Ok(_) => ControlFlow::Continue(Status::Continue),
+ Err(err) => {
self.item_err = Some((self.index, err));
ControlFlow::Continue(Status::Done)
}
diff --git a/src/walk/walkers/core/bool.rs b/src/walk/walkers/core/bool.rs
index 34707d1..c51861a 100644
--- a/src/walk/walkers/core/bool.rs
+++ b/src/walk/walkers/core/bool.rs
@@ -9,7 +9,7 @@ use crate::{
protocol::{
visitor::{RequestHint, Sequence, SequenceScope, Status},
walker::{Hint, HintMeta},
- ControlFlowFor, SyncEffect, Visitor,
+ Yield, SyncEffect, Visitor,
},
};
@@ -36,13 +36,16 @@ impl<'ctx> crate::Walker<'ctx> for Walker {
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx, SyncEffect>,
- ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error> where 'ctx: 'a {
+ ) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, Self::Effect>
+ where
+ 'ctx: 'a,
+ {
{
- if let Some(object) = visitor.upcast_mut::<dyn Value<'_, OwnedStatic<bool>> + '_>() {
+ if let Some(object) = visitor.upcast_mut::<dyn Value<'_, OwnedStatic<bool>, SyncEffect> + '_>() {
object.visit(OwnedStatic(self.0));
}
- ControlFlow::Continue(())
+ Ok(())
}
}
}
diff --git a/tests/demo.rs b/tests/demo.rs
index 9812ef6..c644f73 100644
--- a/tests/demo.rs
+++ b/tests/demo.rs
@@ -6,9 +6,9 @@ use treaty::{
into_walker,
protocol::{
visitor::{Sequence, SequenceScope, Value},
- ControlFlowFor, SyncEffect, Visitor,
+ Yield, SyncEffect, Visitor,
},
- Builder, Walk, Walker,
+ AsVisitor, Builder, Walk, Walker,
};
#[test]
@@ -22,12 +22,12 @@ fn demo() {
dbg!(array_to_array2([true, false]));
dbg!(array_to_array([true, true]));
- let s = build_with::<array::Builder<'_, JsonLike, 3>, _>(into_walker(&a)).unwrap();
+ let s = build_with::<array::Builder<'_, JsonLike, 3, _>, _>(into_walker(&a)).unwrap();
dbg!(s);
use treaty::builders::serde::deserialize::Builder as SerdeBuilder;
- let x = build_with::<SerdeBuilder<serde_json::Value>, _>(into_walker(&a)).unwrap();
+ let x = build_with::<SerdeBuilder<serde_json::Value, _>, _>(into_walker(&a)).unwrap();
dbg!(x);
// let s = build_with::<JsonLike, _>(into_walker(a)).unwrap();
@@ -74,32 +74,38 @@ const _: () = {
fn walk<'a>(
self,
- visitor: &'a mut Visitor<'a, 'ctx>,
- ) -> ControlFlowFor<'a, SyncEffect, Self::Error, Self::Output> {
+ visitor: Visitor<'a, 'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
match self.0 {
Data::Bool(value) => walk_bool(*value, visitor),
Data::Sequence(value) => walk_vec(value, visitor),
}
- core::ops::ControlFlow::Continue(())
+ Ok(())
}
}
};
-fn walk_bool(value: bool, visitor: &mut Visitor<'_, '_>) {
+fn walk_bool(value: bool, visitor: Visitor<'_, '_, SyncEffect>) {
visitor
- .upcast_mut::<dyn Value<OwnedStatic<bool>>>()
+ .upcast_mut::<dyn Value<OwnedStatic<bool>, SyncEffect>>()
.unwrap()
.visit(OwnedStatic(value));
}
-fn walk_vec<'a, 'ctx>(value: &'ctx [Data], visitor: &'a mut Visitor<'a, 'ctx>) {
+fn walk_vec<'a, 'ctx>(value: &'ctx [Data], visitor: Visitor<'a, 'ctx, SyncEffect>) {
struct Scope<'ctx>(VecDeque<&'ctx Data>);
- impl<'ctx> SequenceScope<'ctx> for Scope<'ctx> {
+ impl<'ctx> SequenceScope<'ctx, SyncEffect> for Scope<'ctx> {
fn next<'a>(
&'a mut self,
- visitor: &'a mut Visitor<'a, 'ctx>,
- ) -> ControlFlowFor<'a, SyncEffect, treaty::protocol::visitor::Status> {
+ visitor: Visitor<'a, 'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), treaty::protocol::visitor::Status>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
if let Some(value) = self.0.pop_front() {
into_walker(value).walk(visitor);
@@ -113,7 +119,7 @@ fn walk_vec<'a, 'ctx>(value: &'ctx [Data], visitor: &'a mut Visitor<'a, 'ctx>) {
let mut scope = Scope(value.into_iter().collect());
visitor
- .upcast_mut::<dyn Sequence<'_>>()
+ .upcast_mut::<dyn Sequence<'_, SyncEffect>>()
.unwrap()
.visit(&mut scope);
}
@@ -121,16 +127,12 @@ fn walk_vec<'a, 'ctx>(value: &'ctx [Data], visitor: &'a mut Visitor<'a, 'ctx>) {
#[derive(Default)]
struct JsonLike(String);
-impl<'ctx> Builder<'ctx> for JsonLike {
+impl<'ctx> Builder<'ctx, SyncEffect> for JsonLike {
type Error = ();
type Value = String;
- fn as_visitor(&mut self) -> &mut Visitor<'_, 'ctx> {
- self
- }
-
- fn build(self) -> Result<Self::Value, Self::Error> {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
Ok(self.0)
}
@@ -139,27 +141,41 @@ impl<'ctx> Builder<'ctx> for JsonLike {
fn from_seed(seed: Self::Seed) -> Self {
Self::default()
}
+
+ type Effect = SyncEffect;
+}
+
+impl<'ctx> AsVisitor<'ctx, SyncEffect> for JsonLike {
+ fn as_visitor(&mut self) -> Visitor<'_, 'ctx, SyncEffect> {
+ self
+ }
}
any_trait! {
impl['a, 'ctx] JsonLike = [
- dyn Value<'a, OwnedStatic<bool>> + 'a,
- dyn Sequence<'ctx> + 'a,
+ dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
+ dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
-impl Value<'_, OwnedStatic<bool>> for JsonLike {
- fn visit(&mut self, value: OwnedStatic<bool>) -> ControlFlowFor<'_> {
+impl<'ctx> Value<'ctx, OwnedStatic<bool>, SyncEffect> for JsonLike {
+ fn visit<'a>(&'a mut self, value: OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
self.0.push_str(&format!("{}", value.0));
ControlFlow::Continue(())
}
}
-impl<'ctx> Sequence<'ctx> for JsonLike {
+impl<'ctx> Sequence<'ctx, SyncEffect> for JsonLike {
fn visit<'a>(
&'a mut self,
- scope: &'a mut dyn SequenceScope<'ctx>,
- ) -> ControlFlowFor<'a, SyncEffect> {
+ scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
self.0.push_str("[");
while let ControlFlow::Continue(treaty::protocol::visitor::Status::Continue) =
scope.next(self)
diff --git a/tests/hook.rs b/tests/hook.rs
index 2ad90d5..7746ab1 100644
--- a/tests/hook.rs
+++ b/tests/hook.rs
@@ -1,10 +1,11 @@
-use std::{future::Future, marker::PhantomData, pin::Pin, thread::yield_now, time::Duration};
+use std::{future::Future, marker::PhantomData, pin::Pin, thread::yield_now, time::Duration, ops::ControlFlow};
use treaty::{
any::{any_trait, static_wrapper::OwnedStatic, AnyTrait, IndirectLtAny, LtTypeId},
build_with, into_walker,
protocol::{
- visitor::Value, AnyTraitSendObj, AsyncEffect, ControlFlowFor, Effect, SyncEffect, Visitor, any_t, any_trait_send_obj,
+ any_t, as_obj, visitor::Value, AsObj, AsyncEffect, Yield, Effect, SyncEffect,
+ Visitor, EffectAnyTrait,
},
Build, Builder, Walker,
};
@@ -20,13 +21,22 @@ fn demo() {
todo!();
}
+#[no_mangle]
+fn invert(x: bool) -> bool {
+ let hook = Hook {
+ inner: into_walker(x),
+ _marker: PhantomData,
+ };
+ build_with::<<bool as Build<_>>::Builder, _>(hook).unwrap()
+}
+
struct Hook<T, Effect> {
inner: T,
_marker: PhantomData<fn() -> Effect>,
}
-struct VisitorHook<'a, 'ctx: 'a, E: Effect<'ctx>> {
- inner: any_trait_send_obj::T<'a, 'ctx, E::VisitorHkt>,
+struct VisitorHook<'a, 'ctx: 'a, E: EffectAnyTrait<'ctx>> {
+ inner: as_obj::T<'a, 'ctx, E::AnyTrait>,
}
impl<'ctx, T: Walker<'ctx, Effect = AsyncEffect> + Send> Walker<'ctx> for Hook<T, AsyncEffect>
@@ -43,15 +53,13 @@ where
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx, T::Effect>,
- ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error>
+ ) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, Self::Effect>
where
Self: 'a,
- 'ctx: 'a
+ 'ctx: 'a,
{
Box::pin(async move {
- let mut visitor = VisitorHook::<Self::Effect> {
- inner: visitor,
- };
+ let mut visitor = VisitorHook::<Self::Effect> { inner: visitor };
let flow = self.inner.walk(&mut visitor);
@@ -70,7 +78,7 @@ impl<'ctx, T: Walker<'ctx, Effect = SyncEffect>> Walker<'ctx> for Hook<T, SyncEf
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx, T::Effect>,
- ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error>
+ ) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, Self::Effect>
where
Self: 'a,
'ctx: 'a,
@@ -81,7 +89,7 @@ impl<'ctx, T: Walker<'ctx, Effect = SyncEffect>> Walker<'ctx> for Hook<T, SyncEf
}
}
-impl<'b, 'ctx: 'b, E: Effect<'ctx>> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> {
+impl<'b, 'ctx: 'b, E: Effect<'ctx, ControlFlow<(), ()>>> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> {
fn upcast_to_id<'a>(
&'a self,
id: treaty::any::LtTypeId<'ctx>,
@@ -94,6 +102,7 @@ impl<'b, 'ctx: 'b, E: Effect<'ctx>> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E>
}
}
+ #[inline]
fn upcast_to_id_mut<'a>(
&'a mut self,
id: treaty::any::LtTypeId<'ctx>,
@@ -116,16 +125,19 @@ impl<'b, 'ctx: 'b, E: Effect<'ctx>> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E>
}
}
-impl<'b, 'ctx: 'b, E: Effect<'ctx>> Value<'ctx, OwnedStatic<bool>, E> for VisitorHook<'b, 'ctx, E> {
+impl<'b, 'ctx: 'b, E: Effect<'ctx, ControlFlow<(), ()>>> Value<'ctx, OwnedStatic<bool>, E> for VisitorHook<'b, 'ctx, E> {
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx, E> where 'ctx: 'a {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ where
+ 'ctx: 'a,
+ {
let visitor = self
.inner
.as_obj_mut()
.upcast_mut::<dyn Value<'ctx, OwnedStatic<bool>, E> + 'a>()
.unwrap();
- println!("Hooked bool: {}", value);
+ // println!("Hooked bool: {}", value);
visitor.visit(OwnedStatic(!value))
}
}