added option builder
Konnor Andrews 2024-03-17
parent 9cd9eec · commit e9679b9
-rw-r--r--src/any/static_wrapper.rs12
-rw-r--r--src/build.rs13
-rw-r--r--src/build/builders/core.rs2
-rw-r--r--src/build/builders/core/array.rs26
-rw-r--r--src/build/builders/core/bool.rs20
-rw-r--r--src/build/builders/core/option.rs327
-rw-r--r--src/build/builders/core/variant.rs146
-rw-r--r--src/build/builders/serde/deserialize.rs33
-rw-r--r--src/build/builders/serde/deserialize_seed.rs30
-rw-r--r--src/effect.rs110
-rw-r--r--src/lib.rs1
-rw-r--r--src/protocol.rs138
-rw-r--r--src/protocol/visitor/request_hint.rs8
-rw-r--r--src/protocol/visitor/sequence.rs12
-rw-r--r--src/protocol/visitor/tagged.rs13
-rw-r--r--src/protocol/visitor/value.rs51
-rw-r--r--src/protocol/walker/hint.rs3
-rw-r--r--src/walk.rs5
-rw-r--r--src/walk/walkers/core/array.rs4
-rw-r--r--src/walk/walkers/core/bool.rs12
-rw-r--r--tests/demo.rs20
-rw-r--r--tests/hook.rs37
22 files changed, 790 insertions, 233 deletions
diff --git a/src/any/static_wrapper.rs b/src/any/static_wrapper.rs
index d167257..511982a 100644
--- a/src/any/static_wrapper.rs
+++ b/src/any/static_wrapper.rs
@@ -62,3 +62,15 @@ nameable! {
impl [T] for BoxedStatic<T> where { T: ?Sized + 'static }
impl [T] where BoxedStatic<T> { T: ?Sized + 'static }
}
+
+#[derive(Debug)]
+pub enum BorrowedStaticValue<'ctx, T: ?Sized + 'static> {
+ Ctx(&'ctx T),
+ Static(&'static T),
+}
+
+#[derive(Debug)]
+pub enum BorrowedMutStaticValue<'ctx, T: ?Sized + 'static> {
+ Ctx(&'ctx mut T),
+ Static(&'static mut T),
+}
diff --git a/src/build.rs b/src/build.rs
index b75fa6b..7ac87fd 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -1,7 +1,8 @@
pub mod builders;
use crate::{
- protocol::{AsObj as _, Effect, EffectAnyTrait, SyncEffect, Visitor, Yield},
+ effect::{AsObj as _, Effect, EffectAnyTrait, SyncEffect, Yield},
+ protocol::Visitor,
Walker,
};
@@ -41,7 +42,9 @@ pub trait Builder<'ctx, E: EffectAnyTrait<'ctx>>: AsVisitor<'ctx, E> {
///
/// If an error happened with the builder during the walk
/// it will be reported here.
- fn build<'a>(self) -> Yield<'a, 'ctx, Result<Self::Value, Self::Error>, Self::Effect> where Self: 'a;
+ fn build<'a>(self) -> Yield<'a, 'ctx, Result<Self::Value, Self::Error>, Self::Effect>
+ where
+ Self: 'a;
}
pub trait AsVisitor<'ctx, E: EffectAnyTrait<'ctx>> {
@@ -93,7 +96,11 @@ where
builder.build().map_err(BuildError::Builder)
}
-pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect, Effect = 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
diff --git a/src/build/builders/core.rs b/src/build/builders/core.rs
index 7ea094a..8b4fb45 100644
--- a/src/build/builders/core.rs
+++ b/src/build/builders/core.rs
@@ -1,2 +1,4 @@
pub mod array;
pub mod bool;
+pub mod option;
+// pub mod variant;
diff --git a/src/build/builders/core/array.rs b/src/build/builders/core/array.rs
index 34b8f65..ae4c279 100644
--- a/src/build/builders/core/array.rs
+++ b/src/build/builders/core/array.rs
@@ -2,15 +2,13 @@ use core::{marker::PhantomData, mem::MaybeUninit, ops::ControlFlow};
use crate::{
any_trait,
- protocol::{
- visitor::{Sequence, SequenceScope, Status},
- AsObj as _, Yield, Effect, SyncEffect, EffectAnyTrait,
- },
+ effect::{AsObj as _, Effect, EffectAnyTrait, SyncEffect, Yield},
+ protocol::visitor::{Sequence, SequenceScope, Status},
AsVisitor, DefaultBuilder,
};
#[cfg(feature = "alloc")]
-use crate::protocol::AsyncEffect;
+use crate::effect::AsyncEffect;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
@@ -46,7 +44,10 @@ where
type Value = [B::Value; N];
- fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
+ 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));
}
@@ -75,7 +76,7 @@ where
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>
+ B: crate::Builder<'ctx, SyncEffect, Effect = SyncEffect>,
{
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
self
@@ -97,13 +98,16 @@ any_trait! {
// ]
// }
-impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: EffectAnyTrait<'ctx>> Sequence<'ctx, SyncEffect>
- for Builder<'ctx, B, N, E>
+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>
+ B: crate::Builder<'ctx, E, Effect = SyncEffect>,
{
#[inline]
- fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ fn visit<'a>(
+ &'a mut self,
+ scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs
index c9c0be9..3becdae 100644
--- a/src/build/builders/core/bool.rs
+++ b/src/build/builders/core/bool.rs
@@ -3,7 +3,8 @@ use core::{marker::PhantomData, ops::ControlFlow};
use crate::{
any::static_wrapper::OwnedStatic,
any_trait,
- protocol::{visitor::Value, AsObj, AsyncEffect, Yield, Effect, SyncEffect},
+ effect::{AsObj, AsyncEffect, Effect, SyncEffect, Yield},
+ protocol::visitor::Value,
AsVisitor,
};
@@ -30,7 +31,10 @@ where
type Value = bool;
#[inline]
- fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error>
+ where
+ Self: 'a,
+ {
self.0.ok_or(Error::Incomplete)
}
@@ -57,16 +61,16 @@ impl<'ctx> AsVisitor<'ctx, AsyncEffect> for Builder<AsyncEffect> {
any_trait! {
impl['a, 'ctx, E] Builder<E> = [
- dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
]
}
-impl<'ctx, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<E> {
+impl<'a, 'ctx: 'a, E> Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect> for Builder<E> {
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
- where
- 'ctx: 'a,
- {
+ fn visit(
+ &'a mut self,
+ OwnedStatic(value): OwnedStatic<bool>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
self.0 = Some(value);
ControlFlow::Continue(())
}
diff --git a/src/build/builders/core/option.rs b/src/build/builders/core/option.rs
new file mode 100644
index 0000000..00c79c9
--- /dev/null
+++ b/src/build/builders/core/option.rs
@@ -0,0 +1,327 @@
+use core::{marker::PhantomData, ops::ControlFlow};
+
+use crate::{
+ any::static_wrapper::{BorrowedStatic, BorrowedStaticValue, OwnedStatic, TempBorrowedStatic},
+ any_trait,
+ effect::{AsyncEffect, AsyncSendEffect, EffectAnyTrait, SyncEffect, Yield},
+ protocol::visitor::{Tagged, TaggedScope, Value},
+ AsVisitor,
+};
+
+impl<'ctx, T, E> crate::Build<'ctx, E> for Option<T>
+where
+ E: EffectAnyTrait<'ctx>,
+ Builder<'ctx, T::Builder, E>: AsVisitor<'ctx, E>,
+ T: crate::Build<'ctx, E>,
+{
+ type Builder = Builder<'ctx, T::Builder, E>;
+}
+
+pub struct Builder<'ctx, B: crate::Builder<'ctx, E>, E: EffectAnyTrait<'ctx>> {
+ value: Option<Result<Option<B::Value>, Error<'ctx, B::Error>>>,
+ ignore_missing: bool,
+ _marker: PhantomData<fn() -> (&'ctx (), E)>,
+}
+
+#[derive(Default)]
+pub enum IgnoreMissing {
+ #[default]
+ Yes,
+ No,
+}
+
+#[derive(Debug)]
+pub enum Error<'ctx, T> {
+ Missing,
+ VariantNone,
+ VariantSome(T),
+ UnknownVariantName(Option<BorrowedStaticValue<'ctx, str>>),
+ UnknownVariantNum(Option<u8>),
+ NoVariantGiven,
+}
+
+impl<'ctx, B, E> crate::Builder<'ctx, E> for Builder<'ctx, B, E>
+where
+ E: EffectAnyTrait<'ctx>,
+ Self: AsVisitor<'ctx, E>,
+ B: crate::Builder<'ctx, E>,
+{
+ type Error = Error<'ctx, B::Error>;
+
+ type Value = Option<B::Value>;
+
+ #[inline]
+ fn build<'a>(self) -> Result<Self::Value, Self::Error>
+ where
+ Self: 'a,
+ {
+ match self.value {
+ Some(value) => value,
+ None if self.ignore_missing => Ok(None),
+ None => Err(Error::Missing),
+ }
+ }
+
+ type Seed = IgnoreMissing;
+
+ fn from_seed(seed: Self::Seed) -> Self {
+ Self {
+ value: None,
+ ignore_missing: match seed {
+ IgnoreMissing::Yes => true,
+ IgnoreMissing::No => false,
+ },
+ _marker: PhantomData,
+ }
+ }
+
+ type Effect = SyncEffect;
+}
+
+impl<'ctx, B: crate::Builder<'ctx, SyncEffect>> AsVisitor<'ctx, SyncEffect>
+ for Builder<'ctx, B, SyncEffect>
+{
+ fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
+ self
+ }
+}
+
+impl<'ctx, B: crate::Builder<'ctx, AsyncEffect>> AsVisitor<'ctx, AsyncEffect>
+ for Builder<'ctx, B, AsyncEffect>
+{
+ fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
+ self
+ }
+}
+
+impl<'ctx, B> AsVisitor<'ctx, AsyncSendEffect> for Builder<'ctx, B, AsyncSendEffect>
+where
+ B: crate::Builder<'ctx, AsyncSendEffect>,
+ <B as crate::Builder<'ctx, AsyncSendEffect>>::Value: Send,
+ <B as crate::Builder<'ctx, AsyncSendEffect>>::Error: Send,
+{
+ fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncSendEffect> {
+ self
+ }
+}
+
+any_trait! {
+ impl['a, 'ctx, B] Builder<'ctx, B, SyncEffect> = [
+ ] where B: crate::Builder<'ctx, SyncEffect>
+}
+
+any_trait! {
+ impl['a, 'ctx, B] Builder<'ctx, B, AsyncEffect> = [
+ ] where B: crate::Builder<'ctx, AsyncEffect>
+}
+
+any_trait! {
+ impl['a, 'ctx, B] Builder<'ctx, B, AsyncSendEffect> = [
+ ] where B: crate::Builder<'ctx, AsyncSendEffect>
+}
+
+pub mod symbol {
+ use crate::symbol::Symbol;
+
+ pub const KEY: Symbol = Symbol::new("Key");
+ pub const TYPE: Symbol = Symbol::new("Type");
+ pub const VARIANT: Symbol = Symbol::new("Variant");
+}
+
+impl<'ctx, B> Tagged<'ctx, SyncEffect> for Builder<'ctx, B, SyncEffect>
+where
+ B: crate::DefaultBuilder<'ctx, SyncEffect, Effect = SyncEffect>,
+{
+ fn visit<'a>(
+ &'a mut self,
+ scope: &'a mut dyn TaggedScope<'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
+ match scope.kind() {
+ symbol::KEY | symbol::VARIANT => {
+ // This tag is the variant name/number.
+ let mut variant = VariantVisitor::<'ctx, B::Error> { value: None };
+ scope.tag(&mut variant)?;
+ let variant = match variant.value {
+ Some(Ok(value)) => value,
+ Some(Err(error)) => {
+ self.value = Some(Err(error));
+ return ControlFlow::Break(());
+ }
+ None => {
+ self.value = Some(Err(Error::NoVariantGiven));
+ return ControlFlow::Break(());
+ }
+ };
+
+ match variant {
+ Variant::None => {
+ // Nothing more needs to be done.
+ self.value = Some(Ok(None));
+ ControlFlow::Continue(())
+ }
+ Variant::Some => {
+ // Now build a T.
+ let mut builder = B::default();
+ scope.value(builder.as_visitor())?;
+ match builder.build() {
+ Ok(value) => {
+ self.value = Some(Ok(Some(value)));
+ ControlFlow::Continue(())
+ }
+ Err(error) => {
+ self.value = Some(Err(Error::VariantSome(error)));
+ ControlFlow::Break(())
+ }
+ }
+ }
+ }
+ }
+ _ => {
+ // Ignore any other tags and just use the value.
+ scope.value(self)
+ }
+ }
+ }
+}
+
+enum Variant {
+ None,
+ Some,
+}
+
+pub struct VariantVisitor<'ctx, T> {
+ value: Option<Result<Variant, Error<'ctx, T>>>,
+}
+
+any_trait! {
+ impl['a, 'ctx, T] VariantVisitor<'ctx, T> = [
+ dyn Value<'a, 'ctx, TempBorrowedStatic<'a, str>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, BorrowedStatic<'ctx, str>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, OwnedStatic<&'static str>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, OwnedStatic<u8>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, OwnedStatic<u16>, SyncEffect> + 'a,
+ ]
+}
+
+impl<'a, 'ctx: 'a, T> Value<'a, 'ctx, TempBorrowedStatic<'a, str>, SyncEffect>
+ for VariantVisitor<'ctx, T>
+{
+ fn visit(
+ &'a mut self,
+ TempBorrowedStatic(value): TempBorrowedStatic<'a, str>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
+ match value {
+ "None" => {
+ self.value = Some(Ok(Variant::None));
+ ControlFlow::Continue(())
+ }
+ "Some" => {
+ self.value = Some(Ok(Variant::Some));
+ ControlFlow::Continue(())
+ }
+ _ => {
+ self.value = Some(Err(Error::UnknownVariantName(None)));
+ ControlFlow::Break(())
+ }
+ }
+ }
+}
+
+impl<'a, 'ctx: 'a, T> Value<'a, 'ctx, BorrowedStatic<'ctx, str>, SyncEffect>
+ for VariantVisitor<'ctx, T>
+{
+ fn visit(
+ &'a mut self,
+ BorrowedStatic(value): BorrowedStatic<'ctx, str>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
+ match value {
+ "None" => {
+ self.value = Some(Ok(Variant::None));
+ ControlFlow::Continue(())
+ }
+ "Some" => {
+ self.value = Some(Ok(Variant::Some));
+ ControlFlow::Continue(())
+ }
+ value => {
+ self.value = Some(Err(Error::UnknownVariantName(Some(
+ BorrowedStaticValue::Ctx(value),
+ ))));
+ ControlFlow::Break(())
+ }
+ }
+ }
+}
+
+impl<'a, 'ctx: 'a, T> Value<'a, 'ctx, OwnedStatic<&'static str>, SyncEffect>
+ for VariantVisitor<'ctx, T>
+{
+ fn visit(
+ &'a mut self,
+ OwnedStatic(value): OwnedStatic<&'static str>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
+ match value {
+ "None" => {
+ self.value = Some(Ok(Variant::None));
+ ControlFlow::Continue(())
+ }
+ "Some" => {
+ self.value = Some(Ok(Variant::Some));
+ ControlFlow::Continue(())
+ }
+ value => {
+ self.value = Some(Err(Error::UnknownVariantName(Some(
+ BorrowedStaticValue::Static(value),
+ ))));
+ ControlFlow::Break(())
+ }
+ }
+ }
+}
+
+impl<'a, 'ctx: 'a, T> Value<'a, 'ctx, OwnedStatic<u8>, SyncEffect> for VariantVisitor<'ctx, T> {
+ fn visit(
+ &'a mut self,
+ OwnedStatic(value): OwnedStatic<u8>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
+ match value {
+ 0 => {
+ self.value = Some(Ok(Variant::None));
+ ControlFlow::Continue(())
+ }
+ 1 => {
+ self.value = Some(Ok(Variant::Some));
+ ControlFlow::Continue(())
+ }
+ value => {
+ self.value = Some(Err(Error::UnknownVariantNum(Some(value))));
+ ControlFlow::Break(())
+ }
+ }
+ }
+}
+
+impl<'a, 'ctx: 'a, T> Value<'a, 'ctx, OwnedStatic<u16>, SyncEffect> for VariantVisitor<'ctx, T> {
+ fn visit(
+ &'a mut self,
+ OwnedStatic(value): OwnedStatic<u16>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
+ match value {
+ 0 => {
+ self.value = Some(Ok(Variant::None));
+ ControlFlow::Continue(())
+ }
+ 1 => {
+ self.value = Some(Ok(Variant::Some));
+ ControlFlow::Continue(())
+ }
+ value => {
+ self.value = Some(Err(Error::UnknownVariantNum(value.try_into().ok())));
+ ControlFlow::Break(())
+ }
+ }
+ }
+}
diff --git a/src/build/builders/core/variant.rs b/src/build/builders/core/variant.rs
new file mode 100644
index 0000000..5104a2e
--- /dev/null
+++ b/src/build/builders/core/variant.rs
@@ -0,0 +1,146 @@
+use core::{marker::PhantomData, ops::ControlFlow};
+
+use crate::{
+ any::static_wrapper::OwnedStatic,
+ any_trait,
+ effect::{AsyncEffect, AsyncSendEffect, EffectAnyTrait, SyncEffect, Yield},
+ protocol::visitor::{Tagged, TaggedScope, Value},
+ AsVisitor,
+};
+
+pub struct VariantInfo<'ctx> {
+ pub
+}
+
+pub struct Builder<'ctx, E: EffectAnyTrait<'ctx>> {
+ value: Option<Option<B::Value>>,
+ ignore_missing: bool,
+ _marker: PhantomData<fn() -> (&'ctx (), E)>,
+}
+
+#[derive(Default)]
+pub enum IgnoreMissing {
+ #[default]
+ Yes,
+ No,
+}
+
+#[derive(Debug)]
+pub enum Error<T> {
+ Missing,
+ VariantNone,
+ VariantSome(T),
+}
+
+impl<'ctx, B, E> crate::Builder<'ctx, E> for Builder<'ctx, B, E>
+where
+ E: EffectAnyTrait<'ctx>,
+ Self: AsVisitor<'ctx, E>,
+ B: crate::Builder<'ctx, E>,
+{
+ type Error = Error<B::Error>;
+
+ type Value = Option<B::Value>;
+
+ #[inline]
+ fn build<'a>(self) -> Result<Self::Value, Self::Error>
+ where
+ Self: 'a,
+ {
+ if self.ignore_missing {
+ Ok(self.value.flatten())
+ } else {
+ self.value.ok_or(Error::Missing)
+ }
+ }
+
+ type Seed = IgnoreMissing;
+
+ fn from_seed(seed: Self::Seed) -> Self {
+ Self {
+ value: None,
+ ignore_missing: match seed {
+ IgnoreMissing::Yes => true,
+ IgnoreMissing::No => false,
+ },
+ _marker: PhantomData,
+ }
+ }
+
+ type Effect = SyncEffect;
+}
+
+impl<'ctx, B: crate::Builder<'ctx, SyncEffect>> AsVisitor<'ctx, SyncEffect>
+ for Builder<'ctx, B, SyncEffect>
+{
+ fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
+ self
+ }
+}
+
+impl<'ctx, B: crate::Builder<'ctx, AsyncEffect>> AsVisitor<'ctx, AsyncEffect>
+ for Builder<'ctx, B, AsyncEffect>
+{
+ fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
+ self
+ }
+}
+
+impl<'ctx, B> AsVisitor<'ctx, AsyncSendEffect> for Builder<'ctx, B, AsyncSendEffect>
+where
+ B: crate::Builder<'ctx, AsyncSendEffect>,
+ <B as crate::Builder<'ctx, AsyncSendEffect>>::Value: Send,
+{
+ fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncSendEffect> {
+ self
+ }
+}
+
+any_trait! {
+ impl['a, 'ctx, B] Builder<'ctx, B, SyncEffect> = [
+ ] where B: crate::Builder<'ctx, SyncEffect>
+}
+
+any_trait! {
+ impl['a, 'ctx, B] Builder<'ctx, B, AsyncEffect> = [
+ ] where B: crate::Builder<'ctx, AsyncEffect>
+}
+
+any_trait! {
+ impl['a, 'ctx, B] Builder<'ctx, B, AsyncSendEffect> = [
+ ] where B: crate::Builder<'ctx, AsyncSendEffect>
+}
+
+pub mod symbol {
+ use crate::symbol::Symbol;
+
+ pub const TYPE: Symbol = Symbol::new("Type");
+ pub const VARIANT: Symbol = Symbol::new("Variant");
+}
+
+impl<'ctx, B> Tagged<'ctx, SyncEffect> for Builder<'ctx, B, SyncEffect>
+where
+ B: crate::Builder<'ctx, SyncEffect>,
+{
+ fn visit<'a>(
+ &'a mut self,
+ scope: &'a mut dyn TaggedScope<'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ where
+ 'ctx: 'a,
+ {
+ match scope.kind() {
+ symbol::TYPE => {
+ // The type info doesn't matter, just move on to the value.
+ scope.value(self)?;
+ },
+ symbol::VARIANT => {
+ // We need to check the variant id.
+ // let mut variant = VariantBuilder::from_seed(());
+ },
+ _ => {}
+ }
+
+ todo!();
+ }
+}
diff --git a/src/build/builders/serde/deserialize.rs b/src/build/builders/serde/deserialize.rs
index 8a9fa3e..1daa30f 100644
--- a/src/build/builders/serde/deserialize.rs
+++ b/src/build/builders/serde/deserialize.rs
@@ -7,10 +7,8 @@ use serde::{de::SeqAccess, forward_to_deserialize_any, Deserialize, Deserializer
use crate::{
any::static_wrapper::OwnedStatic,
any_trait,
- protocol::{
- visitor::{Sequence, SequenceScope, Status, Value},
- AsObj, AsyncEffect, Yield, Effect, SyncEffect,
- },
+ effect::{AsObj, AsyncEffect, Effect, SyncEffect, Yield},
+ protocol::visitor::{Sequence, SequenceScope, Status, Value},
AsVisitor, Builder as _,
};
@@ -25,7 +23,8 @@ 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, ControlFlow<(), ()>>> 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 +32,10 @@ where
type Value = T;
- fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error>
+ where
+ Self: 'a,
+ {
self.0
}
@@ -60,7 +62,7 @@ impl<'ctx, T: Deserialize<'ctx> + Send> AsVisitor<'ctx, AsyncEffect> for Builder
any_trait! {
impl['a, 'ctx, T: Deserialize<'ctx>, E] Builder<T, E> = [
- dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
@@ -70,12 +72,14 @@ enum InjectedValue<'a, 'ctx> {
Sequence(&'a mut dyn SequenceScope<'ctx, SyncEffect>),
}
-impl<'ctx, T: Deserialize<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<T, E> {
+impl<'a, 'ctx: 'a, T: Deserialize<'ctx>, E> Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect>
+ for Builder<T, E>
+{
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
- where
- 'ctx: 'a,
- {
+ fn visit(
+ &'a mut self,
+ OwnedStatic(value): OwnedStatic<bool>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
self.0 = T::deserialize(InjectedValue::Bool(value));
if self.0.is_err() {
@@ -88,7 +92,10 @@ impl<'ctx, T: Deserialize<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> f
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, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ fn visit<'a>(
+ &'a mut self,
+ scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
diff --git a/src/build/builders/serde/deserialize_seed.rs b/src/build/builders/serde/deserialize_seed.rs
index 23434cf..dce34c0 100644
--- a/src/build/builders/serde/deserialize_seed.rs
+++ b/src/build/builders/serde/deserialize_seed.rs
@@ -10,10 +10,8 @@ use serde::{
use crate::{
any::static_wrapper::OwnedStatic,
any_trait,
- protocol::{
- visitor::{Sequence, SequenceScope, Status, Value},
- AsObj, AsyncEffect, Yield, Effect, SyncEffect,
- },
+ effect::{AsObj, AsyncEffect, Effect, SyncEffect, Yield},
+ protocol::visitor::{Sequence, SequenceScope, Status, Value},
AsVisitor, Builder as _,
};
@@ -46,12 +44,14 @@ impl<'ctx, T: DeserializeSeed<'ctx>, E: Effect<'ctx, ControlFlow<(), ()>>> crate
where
Self: AsVisitor<'ctx, E>,
{
-
type Error = Error<T>;
type Value = T::Value;
- fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error>
+ where
+ Self: 'a,
+ {
self.0
}
@@ -82,7 +82,7 @@ where
any_trait! {
impl['a, 'ctx, T: DeserializeSeed<'ctx>, E] Builder<'ctx, T, E> = [
- dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
@@ -93,15 +93,14 @@ enum InjectedValue<'a, 'ctx, T> {
Extra(PhantomData<T>),
}
-impl<'ctx, T: DeserializeSeed<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<'ctx, T, E> {
+impl<'a, 'ctx: 'a, T: DeserializeSeed<'ctx>, E> Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect>
+ for Builder<'ctx, T, E>
+{
#[inline]
- fn visit<'a>(
+ fn visit(
&'a mut self,
OwnedStatic(bool_value): OwnedStatic<bool>,
- ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
- where
- 'ctx: 'a,
- {
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
let pending = core::mem::replace(&mut self.0, Err(Error::Incomplete));
let Err(Error::Pending(value)) = pending else {
todo!()
@@ -119,7 +118,10 @@ impl<'ctx, T: DeserializeSeed<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffec
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, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
+ fn visit<'a>(
+ &'a mut self,
+ scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
diff --git a/src/effect.rs b/src/effect.rs
new file mode 100644
index 0000000..dd8b971
--- /dev/null
+++ b/src/effect.rs
@@ -0,0 +1,110 @@
+use crate::{any::AnyTrait, hkt, type_class};
+
+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> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) {
+ fn as_obj(&self) -> &dyn AnyTrait<'ctx> {
+ *self
+ }
+
+ fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx> {
+ *self
+ }
+
+ fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx> {
+ self
+ }
+}
+
+impl<'a, 'ctx: 'a> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + Send + 'a) {
+ fn as_obj(&self) -> &dyn AnyTrait<'ctx> {
+ *self
+ }
+
+ fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx> {
+ *self
+ }
+
+ fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx> {
+ self
+ }
+}
+
+type_class!(for<'lt, 'ctx> pub as_obj: AsObj<'lt, 'ctx>);
+type_class!(for<'lt, 'ctx> pub any_t);
+
+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>;
+}
+
+/// 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!((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 SyncYield[T] => T);
+
+impl<'ctx, T> Effect<'ctx, T> for SyncEffect {
+ type Yield = SyncYield<'ctx, T>;
+}
+
+impl<'ctx> EffectAnyTrait<'ctx> for SyncEffect {
+ type AnyTrait = AnyTraitObj<'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 AsyncYield[T] =>
+ core::pin::Pin<
+ Box<dyn core::future::Future<Output = T> + 'a>,
+ >
+);
+
+#[cfg(feature = "alloc")]
+pub enum AsyncEffect {}
+
+#[cfg(feature = "alloc")]
+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/lib.rs b/src/lib.rs
index f175c63..fd78f63 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,6 +9,7 @@ extern crate alloc;
pub mod any;
mod build;
+pub mod effect;
pub mod hkt;
pub mod protocol;
pub mod symbol;
diff --git a/src/protocol.rs b/src/protocol.rs
index 4ad6d8d..605551a 100644
--- a/src/protocol.rs
+++ b/src/protocol.rs
@@ -1,3 +1,22 @@
+//! A collection of built in protocols between walkers and visitors.
+//!
+//! Treaty has not set data model. Instead, this module contains a set of basic protocols
+//! walkers and visitors can use to exchange information.
+//!
+//! | Rust Type (`T`) | Protocol |
+//! |-----------|----------|
+//! | `bool` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] |
+//! | `i8`, `i16`, `i32`, `i64`, `i128`, `isize` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] |
+//! | `u8`, `u16`, `u32`, `u64`, `u128`, `usize` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] |
+//! | `f32`, `f64` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] |
+//! | `char` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] |
+//! | `String` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] |
+//! | `Vec<u8>` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] |
+//! | `&'ctx str` | [`dyn Value<'ctx, BorrowedStatic<'ctx, T>, _>`][visitor::Value] |
+//! | `&'ctx [u8]` | [`dyn Value<'ctx, BorrowedStatic<'ctx, T>, _>`][visitor::Value] |
+//!
+//!
+//!
//! Interface for interfaces.
//!
//! ## Design
@@ -41,8 +60,11 @@ use core::{
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
-use crate::any::AnyTrait;
use crate::hkt::{hkt, type_class};
+use crate::{
+ any::AnyTrait,
+ effect::{as_obj, EffectAnyTrait},
+};
pub mod visitor;
pub mod walker;
@@ -51,115 +73,5 @@ pub mod walker;
use alloc::boxed::Box;
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 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> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) {
- fn as_obj(&self) -> &dyn AnyTrait<'ctx> {
- *self
- }
-
- fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx> {
- *self
- }
-
- fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx> {
- self
- }
-}
-
-impl<'a, 'ctx: 'a> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + Send + 'a) {
- fn as_obj(&self) -> &dyn AnyTrait<'ctx> {
- *self
- }
-
- fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx> {
- *self
- }
-
- fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx> {
- self
- }
-}
-
-type_class!(for<'lt, 'ctx> pub as_obj: AsObj<'lt, 'ctx>);
-type_class!(for<'lt, 'ctx> pub any_t);
-
-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>;
-}
-
-/// 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!((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 SyncYield[T] => T);
-
-impl<'ctx, T> Effect<'ctx, T> for SyncEffect {
- type Yield = SyncYield<'ctx, T>;
-}
-
-impl<'ctx> EffectAnyTrait<'ctx> for SyncEffect {
- type AnyTrait = AnyTraitObj<'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 AsyncYield[T] =>
- core::pin::Pin<
- Box<dyn core::future::Future<Output = T> + 'a>,
- >
-);
-
-#[cfg(feature = "alloc")]
-pub enum AsyncEffect {}
-
-#[cfg(feature = "alloc")]
-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>;
-}
+ as_obj::T<'a, 'ctx, <Effect as EffectAnyTrait<'ctx>>::AnyTrait>;
+pub type Walker<'a, 'ctx, Effect> = as_obj::T<'a, 'ctx, <Effect as EffectAnyTrait<'ctx>>::AnyTrait>;
diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs
index d79ef73..c7aa847 100644
--- a/src/protocol/visitor/request_hint.rs
+++ b/src/protocol/visitor/request_hint.rs
@@ -1,8 +1,9 @@
use core::ops::ControlFlow;
use crate::{
+ effect::{Effect, SyncEffect, Yield},
nameable,
- protocol::{Yield, Effect, SyncEffect, Walker},
+ protocol::Walker,
};
/// Protocol for requesting a hint from a visitor.
@@ -11,7 +12,10 @@ pub trait RequestHint<'a, 'ctx: 'a, E: Effect<'ctx, ControlFlow<(), ()>>> {
///
/// `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>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>;
+ fn request_hint(
+ &'a mut self,
+ walker: Walker<'a, 'ctx, E>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>;
}
nameable! {
diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs
index d345ed1..2a5f9f3 100644
--- a/src/protocol/visitor/sequence.rs
+++ b/src/protocol/visitor/sequence.rs
@@ -1,9 +1,10 @@
use core::ops::ControlFlow;
use crate::{
+ effect::{any_t, Effect, SyncEffect, Yield},
hkt::hkt,
nameable,
- protocol::{any_t, walker::HintMeta, Yield, Effect, SyncEffect, Visitor},
+ protocol::{walker::HintMeta, Visitor},
};
pub trait Sequence<'ctx, E: Effect<'ctx, ControlFlow<(), ()>>> {
@@ -33,7 +34,10 @@ pub trait SequenceScope<'ctx, E>
where
E: Effect<'ctx, ControlFlow<(), Status>>,
{
- fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> Yield<'a, 'ctx, ControlFlow<(), Status>, E>
+ fn next<'a>(
+ &'a mut self,
+ visitor: Visitor<'a, 'ctx, E>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), Status>, E>
where
'ctx: 'a;
}
@@ -55,7 +59,9 @@ pub struct Hint {
pub len: (usize, Option<usize>),
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx, ControlFlow<(), ()>>> HintMeta<'ctx> for dyn Sequence<'ctx, E> + '_ {
+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 0bc90a0..9b5caf5 100644
--- a/src/protocol/visitor/tagged.rs
+++ b/src/protocol/visitor/tagged.rs
@@ -1,9 +1,10 @@
use core::ops::ControlFlow;
use crate::{
+ effect::{any_t, Effect, SyncEffect, Yield},
hkt::hkt,
nameable,
- protocol::{any_t, walker::HintMeta, Yield, Effect, SyncEffect, Visitor},
+ protocol::{walker::HintMeta, Visitor},
symbol::Symbol,
};
@@ -33,11 +34,17 @@ nameable! {
pub trait TaggedScope<'ctx, E: Effect<'ctx, ControlFlow<(), ()>>> {
fn kind(&mut self) -> Symbol;
- fn tag<'a>(&'a mut self, visitor: Visitor<'a, 'ctx, E>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ 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>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ fn value<'a>(
+ &'a mut self,
+ visitor: Visitor<'a, 'ctx, E>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
where
'ctx: 'a;
}
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index ed3a0bd..20c55d9 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -6,15 +6,16 @@ use core::ops::ControlFlow;
use crate::{
any::{TypeName, TypeNameable},
+ effect::{any_t, Effect, SyncEffect, Yield},
hkt::hkt,
nameable,
- protocol::{any_t, walker::HintMeta, Effect, SyncEffect, Yield},
+ protocol::walker::HintMeta,
};
/// Trait object for the [`Value`] protocol.
///
/// Types implementing the [`Value`] protocol will implement this trait.
-pub trait Value<'ctx, T, E: Effect<'ctx, ControlFlow<(), ()>>> {
+pub trait Value<'a, 'ctx: 'a, 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
@@ -24,21 +25,19 @@ pub trait Value<'ctx, T, E: Effect<'ctx, ControlFlow<(), ()>>> {
/// 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) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
- where
- 'ctx: 'a;
+ fn visit(&'a mut self, value: T) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>;
}
nameable! {
pub struct Name['a, 'ctx, T, E];
- impl [T::Name, E] for dyn Value<'ctx, T, E> + 'a where {
+ impl [T::Name, E] for dyn Value<'a, 'ctx, T, E> + 'a where {
T: TypeNameable<'a, 'ctx> + ?Sized,
E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a,
}
- impl [T, E] where dyn Value<'ctx, T::Nameable, E> + 'a {
+ impl [T, E] where dyn Value<'a, 'ctx, T::Nameable, E> + 'a {
T: TypeName<'a, 'ctx> + ?Sized,
E: Effect<'ctx, ControlFlow<(), ()>>,
'ctx: 'a,
@@ -49,7 +48,7 @@ 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, ControlFlow<(), ()>>> HintMeta<'ctx>
- for dyn Value<'ctx, T, E> + 'a
+ for dyn Value<'a, 'ctx, T, E> + 'a
{
type Known = KnownHkt<'ctx>;
@@ -74,27 +73,21 @@ mod test {
fn visit() {
struct Visitor(Option<i32>);
- impl<'ctx> Value<'ctx, OwnedStatic<i32>> for Visitor {
- fn visit<'a>(
+ impl<'a, 'ctx: 'a> Value<'a, 'ctx, OwnedStatic<i32>, SyncEffect> for Visitor {
+ fn visit(
&'a mut self,
OwnedStatic(value): OwnedStatic<i32>,
- ) -> core::ops::ControlFlow<()>
- where
- 'ctx: 'a,
- {
+ ) -> core::ops::ControlFlow<()> {
self.0 = Some(value);
ControlFlow::Continue(())
}
}
- impl<'ctx> Value<'ctx, BorrowedStatic<'ctx, i32>> for Visitor {
- fn visit<'a>(
+ impl<'a, 'ctx: 'a> Value<'a, 'ctx, BorrowedStatic<'ctx, i32>, SyncEffect> for Visitor {
+ fn visit(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, i32>,
- ) -> core::ops::ControlFlow<()>
- where
- 'ctx: 'a,
- {
+ ) -> core::ops::ControlFlow<()> {
self.0 = Some(*value);
ControlFlow::Continue(())
}
@@ -129,14 +122,11 @@ mod test {
fn visit_borrowed() {
struct Visitor<'ctx>(Option<&'ctx mut String>);
- impl<'ctx> Value<'ctx, BorrowedMutStatic<'ctx, String>> for Visitor<'ctx> {
- fn visit<'a>(
+ impl<'a, 'ctx> Value<'a, 'ctx, BorrowedMutStatic<'ctx, String>, SyncEffect> for Visitor<'ctx> {
+ fn visit(
&'a mut self,
BorrowedMutStatic(value): BorrowedMutStatic<'ctx, String>,
- ) -> ControlFlow<()>
- where
- 'ctx: 'a,
- {
+ ) -> ControlFlow<()> {
self.0 = Some(value);
ControlFlow::Continue(())
}
@@ -165,14 +155,11 @@ mod test {
fn visit_borrowed_unsized() {
struct Visitor<'ctx>(Option<&'ctx str>);
- impl<'ctx> Value<'ctx, BorrowedStatic<'ctx, str>> for Visitor<'ctx> {
- fn visit<'a>(
+ impl<'a, 'ctx: 'a> Value<'a, 'ctx, BorrowedStatic<'ctx, str>, SyncEffect> for Visitor<'ctx> {
+ fn visit(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, str>,
- ) -> ControlFlow<()>
- where
- 'ctx: 'a,
- {
+ ) -> ControlFlow<()> {
self.0 = Some(value);
ControlFlow::Continue(())
}
diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs
index 56d5793..46ad675 100644
--- a/src/protocol/walker/hint.rs
+++ b/src/protocol/walker/hint.rs
@@ -8,8 +8,9 @@ use core::ops::ControlFlow;
use crate::{
any::{TypeName, TypeNameable},
+ effect::{any_t, Effect, EffectAnyTrait, SyncEffect, Yield},
nameable,
- protocol::{any_t, Effect, EffectAnyTrait, SyncEffect, Visitor, Yield},
+ protocol::Visitor,
};
/// Meta information for the hint.
diff --git a/src/walk.rs b/src/walk.rs
index 384760a..582af96 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -1,6 +1,9 @@
pub mod walkers;
-use crate::protocol::{Effect, EffectAnyTrait, Visitor, Yield};
+use crate::{
+ effect::{Effect, Yield},
+ protocol::Visitor,
+};
/// A type that can be walked.
pub trait Walk<'ctx>: Sized {
diff --git a/src/walk/walkers/core/array.rs b/src/walk/walkers/core/array.rs
index 4154e50..c4b9568 100644
--- a/src/walk/walkers/core/array.rs
+++ b/src/walk/walkers/core/array.rs
@@ -1,12 +1,12 @@
-use crate::protocol::Effect;
use core::{mem::MaybeUninit, ops::ControlFlow};
use crate::{
any_trait,
+ effect::{Effect, SyncEffect, Yield},
protocol::{
visitor::{RequestHint, Sequence, SequenceScope, Status},
walker::{Hint, HintMeta},
- Yield, SyncEffect, Visitor,
+ Visitor,
},
};
diff --git a/src/walk/walkers/core/bool.rs b/src/walk/walkers/core/bool.rs
index c51861a..0fd9cbd 100644
--- a/src/walk/walkers/core/bool.rs
+++ b/src/walk/walkers/core/bool.rs
@@ -1,15 +1,13 @@
-use crate::{
- any::static_wrapper::OwnedStatic,
- protocol::{visitor::Value, Effect},
-};
+use crate::{any::static_wrapper::OwnedStatic, protocol::visitor::Value};
use core::{mem::MaybeUninit, ops::ControlFlow};
use crate::{
any_trait,
+ effect::{Effect, SyncEffect, Yield},
protocol::{
visitor::{RequestHint, Sequence, SequenceScope, Status},
walker::{Hint, HintMeta},
- Yield, SyncEffect, Visitor,
+ Visitor,
},
};
@@ -41,7 +39,9 @@ impl<'ctx> crate::Walker<'ctx> for Walker {
'ctx: 'a,
{
{
- if let Some(object) = visitor.upcast_mut::<dyn Value<'_, OwnedStatic<bool>, SyncEffect> + '_>() {
+ if let Some(object) =
+ visitor.upcast_mut::<dyn Value<'_, '_, OwnedStatic<bool>, SyncEffect> + '_>()
+ {
object.visit(OwnedStatic(self.0));
}
diff --git a/tests/demo.rs b/tests/demo.rs
index c644f73..b6bf557 100644
--- a/tests/demo.rs
+++ b/tests/demo.rs
@@ -3,10 +3,11 @@ use treaty::{
any::{any_trait, static_wrapper::OwnedStatic},
build, build_with,
builders::core::array,
+ effect::{SyncEffect, Yield},
into_walker,
protocol::{
visitor::{Sequence, SequenceScope, Value},
- Yield, SyncEffect, Visitor,
+ Visitor,
},
AsVisitor, Builder, Walk, Walker,
};
@@ -132,7 +133,10 @@ impl<'ctx> Builder<'ctx, SyncEffect> for JsonLike {
type Value = String;
- fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
+ fn build<'a>(self) -> Result<Self::Value, Self::Error>
+ where
+ Self: 'a,
+ {
Ok(self.0)
}
@@ -153,16 +157,16 @@ impl<'ctx> AsVisitor<'ctx, SyncEffect> for JsonLike {
any_trait! {
impl['a, 'ctx] JsonLike = [
- dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
+ dyn Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
-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,
- {
+impl<'a, 'ctx: 'a> Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect> for JsonLike {
+ fn visit(
+ &'a mut self,
+ value: OwnedStatic<bool>,
+ ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> {
self.0.push_str(&format!("{}", value.0));
ControlFlow::Continue(())
}
diff --git a/tests/hook.rs b/tests/hook.rs
index 7746ab1..9dacb62 100644
--- a/tests/hook.rs
+++ b/tests/hook.rs
@@ -1,12 +1,14 @@
-use std::{future::Future, marker::PhantomData, pin::Pin, thread::yield_now, time::Duration, ops::ControlFlow};
+use std::{
+ future::Future, marker::PhantomData, ops::ControlFlow, pin::Pin, thread::yield_now,
+ time::Duration,
+};
use treaty::{
any::{any_trait, static_wrapper::OwnedStatic, AnyTrait, IndirectLtAny, LtTypeId},
- build_with, into_walker,
- protocol::{
- any_t, as_obj, visitor::Value, AsObj, AsyncEffect, Yield, Effect, SyncEffect,
- Visitor, EffectAnyTrait,
- },
+ build_with,
+ effect::{any_t, as_obj, AsObj, AsyncEffect, Effect, EffectAnyTrait, SyncEffect, Yield},
+ into_walker,
+ protocol::{visitor::Value, Visitor},
Build, Builder, Walker,
};
@@ -16,7 +18,9 @@ fn demo() {
inner: into_walker(true),
_marker: PhantomData,
};
- let x = build_with::<<bool as Build<_>>::Builder, _>(hook).unwrap();
+ // let x = build_with::<<bool as Build<_>>::Builder, _>(hook).unwrap();
+ // dbg!(x);
+ let x = build_with::<<Option<bool> as Build<_>>::Builder, _>(hook).unwrap();
dbg!(x);
todo!();
}
@@ -89,7 +93,9 @@ impl<'ctx, T: Walker<'ctx, Effect = SyncEffect>> Walker<'ctx> for Hook<T, SyncEf
}
}
-impl<'b, 'ctx: 'b, E: Effect<'ctx, ControlFlow<(), ()>>> 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>,
@@ -111,10 +117,10 @@ impl<'b, 'ctx: 'b, E: Effect<'ctx, ControlFlow<(), ()>>> AnyTrait<'ctx> for Visi
'ctx: 'a,
{
match id {
- id if id == LtTypeId::of::<dyn Value<'ctx, OwnedStatic<bool>, E> + 'a>() => {
+ id if id == LtTypeId::of::<dyn Value<'_, 'ctx, OwnedStatic<bool>, E> + 'a>() => {
if self.inner.as_obj_mut().upcast_to_id_mut(id).is_some() {
Some(IndirectLtAny::<'a, 'ctx, _>::new::<
- dyn Value<'ctx, OwnedStatic<bool>, E> + 'a,
+ dyn Value<'_, 'ctx, OwnedStatic<bool>, E> + 'a,
>(self as _))
} else {
None
@@ -125,16 +131,21 @@ impl<'b, 'ctx: 'b, E: Effect<'ctx, ControlFlow<(), ()>>> AnyTrait<'ctx> for Visi
}
}
-impl<'b, 'ctx: 'b, E: Effect<'ctx, ControlFlow<(), ()>>> Value<'ctx, OwnedStatic<bool>, E> for VisitorHook<'b, 'ctx, E> {
+impl<'a, 'b, 'ctx: 'b + 'a, E: Effect<'ctx, ControlFlow<(), ()>>> Value<'a, 'ctx, OwnedStatic<bool>, E>
+ for VisitorHook<'b, 'ctx, E>
+{
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, E>
+ fn visit(
+ &'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>()
+ .upcast_mut::<dyn Value<'a, 'ctx, OwnedStatic<bool>, E> + 'a>()
.unwrap();
// println!("Hooked bool: {}", value);