cleaned up
Konnor Andrews 2024-04-14
parent d9dd39d · commit 0a6381b
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml12
-rw-r--r--src/any.rs25
-rw-r--r--src/any/indirect.rs30
-rw-r--r--src/any/static_wrapper.rs38
-rw-r--r--src/any/type_name_id.rs2
-rw-r--r--src/build.rs2
-rw-r--r--src/build/builders/core/bool.rs17
-rw-r--r--src/build/builders/debug.rs92
-rw-r--r--src/effect.rs2
-rw-r--r--src/hkt.rs97
-rw-r--r--src/lib.rs13
-rw-r--r--src/protocol/visitor.rs48
-rw-r--r--src/protocol/visitor/recoverable.rs30
-rw-r--r--src/protocol/visitor/request_hint.rs12
-rw-r--r--src/protocol/visitor/sequence.rs24
-rw-r--r--src/protocol/visitor/tag.rs75
-rw-r--r--src/protocol/visitor/value.rs359
-rw-r--r--src/walk.rs2
-rw-r--r--src/walk/walkers/core/key_value.rs25
-rw-r--r--src/walk/walkers/core/struct.rs133
-rw-r--r--src/walk/walkers/core/tag.rs16
-rw-r--r--src/walk/walkers/core/value.rs8
-rw-r--r--tests/common/builder.rs7
-rw-r--r--tests/common/protocol.rs2
-rw-r--r--tests/common/protocol/tag.rs16
-rw-r--r--tests/common/protocol/visitor.rs30
-rw-r--r--tests/protocol_visitor_value.rs1
-rw-r--r--tests/walkers/core/struct.rs32
29 files changed, 612 insertions, 539 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 23e5987..e2d220c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -618,7 +618,6 @@ dependencies = [
"macro_rules_attribute",
"mockall",
"proptest",
- "serde",
"serde_json",
"tokio",
]
diff --git a/Cargo.toml b/Cargo.toml
index 8fc6d84..cb4a994 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,16 +7,16 @@ description = "Next generation serialization"
repository = "https://gitlab.com/konnorandrews/treaty"
readme = "README.md"
-include = ["LICENSE-APACHE", "LICENSE-MIT", "README.md", "empty.rs"]
+# include = ["LICENSE-APACHE", "LICENSE-MIT", "README.md", "empty.rs"]
[dependencies]
-serde = { version = "1.0", default-features = false, optional = true }
+# serde = { version = "1.0", default-features = false, optional = true }
[features]
-default = ["std", "serde", "better_errors"]
-std = ["alloc", "serde?/std"]
-alloc = ["serde?/alloc"]
-serde = ["dep:serde"]
+default = ["std", "better_errors"]
+std = ["alloc"]
+alloc = []
+# serde = ["dep:serde"]
better_errors = []
[dev-dependencies]
diff --git a/src/any.rs b/src/any.rs
index 5df514c..488f6f3 100644
--- a/src/any.rs
+++ b/src/any.rs
@@ -3,12 +3,13 @@
//! The `AnyTrait` trait provides dynamic upcasting to trait objects.
pub mod indirect;
-pub mod static_wrapper;
+mod static_wrapper;
mod type_name_id;
use crate::{bijective_higher_ranked_trait, bijective_higher_ranked_type, hkt::Invariant};
use core::marker::PhantomData;
+pub use static_wrapper::*;
pub use type_name_id::*;
#[cfg(all(feature = "alloc", not(feature = "std")))]
@@ -31,13 +32,13 @@ bijective_higher_ranked_trait! {
///
/// Types of this class can usually be sealed as they don't need to be named directly.
///
- /// Higher ranked types of this form have a [`TypeId`] associated with them.
+ /// Higher ranked types of this form have a [`TypeId`][core::any::TypeId] associated with them.
/// This allows them to be used as a name for lifetime containing types.
///
/// This type class has members in the [`WithContextLt`] higher ranked type class.
/// To get a concrete type two lowerings need to be applied to inject two lifetimes.
/// One for the context lifetime, and one for the lifetime of the concrete type.
- pub type class TypeName[][]: {'static} [for<'ctx> WithContextLt::MemberType<'ctx> + Send]
+ pub type class TypeName[][]: {'static} [for<'ctx> WithContextLt::MemberType<'ctx>]
}
bijective_higher_ranked_type! {
@@ -208,8 +209,8 @@ impl<'b, 'ctx: 'b> dyn AnyTrait<'ctx> + Send + 'b {
pub fn upcast<'a, Trait: ?Sized + TypeName::LowerType<'ctx>>(
&'a self,
) -> Option<&'a WithContextLt::T<'a, 'ctx, Trait>> {
- self.upcast_to_id(TypeNameId::of::<Trait>()).map(|object| {
- match object.downcast() {
+ self.upcast_to_id(TypeNameId::of::<Trait>())
+ .map(|object| match object.downcast() {
Ok(object) => object,
Err(object) => panic!(
"Unexpected trait object. This means a bad impl of \
@@ -217,8 +218,7 @@ impl<'b, 'ctx: 'b> dyn AnyTrait<'ctx> + Send + 'b {
TypeNameId::of::<Trait>(),
object.id()
),
- }
- })
+ })
}
/// Upcast a mutable borrow to the given trait object type.
@@ -333,7 +333,7 @@ use self::indirect::{sealed::RawIndirect, Indirect};
///
/// `&'a dyn MyTrait<ctx>` becomes `AnyTraitObject<'a, 'ctx, Ref>`.
///
-/// The `I` generic is the flavor if pointer being used. It can be [`Ref`] or [`Mut`].
+/// The `I` generic is the flavor if pointer being used. It can be [`Ref`][indirect::Ref] or [`Mut`][indirect::Mut].
#[must_use]
pub struct AnyTraitObject<'a, 'ctx: 'a, I: Indirect<'a>> {
/// The extra vtable pointer.
@@ -378,7 +378,7 @@ impl<'a, 'ctx, I: Indirect<'a>> AnyTraitObject<'a, 'ctx, I> {
/// returned as is.
pub fn downcast<T: ?Sized + WithContextLt::LowerType<'a, 'ctx>>(
self,
- ) -> Result<I::ForT<T>, Self>
+ ) -> Result<I::ForT<T>, Self>
where
WithContextLt::HigherRanked<'a, 'ctx, T>: TypeName::LowerType<'ctx>,
{
@@ -450,7 +450,7 @@ mod test {
// We have the type tower: T<'a, 'ctx> <-> DynT<'ctx> <-> NameT
// We want every T, DynT, NameT set to be unique.
//
- // Assume there was a U that tried to use NameT in it's type tower:
+ // Assume there was a U that tried to use NameT in it's type tower:
// U<'a, 'ctx> <-> DynU<'ctx> <-> NameT
//
// If we traverse the type tower in this order: T -r-> A -r-> B -l-> C -l-> D
@@ -464,7 +464,10 @@ mod test {
x: &WithContextLt::T<
'a,
'ctx,
- TypeName::T<'ctx, TypeName::HigherRanked<'ctx, WithContextLt::HigherRanked<'a, 'ctx, T>>>,
+ TypeName::T<
+ 'ctx,
+ TypeName::HigherRanked<'ctx, WithContextLt::HigherRanked<'a, 'ctx, T>>,
+ >,
>,
) where
T: WithContextLt::LowerType<'a, 'ctx>,
diff --git a/src/any/indirect.rs b/src/any/indirect.rs
index ae70ef3..ffd3b78 100644
--- a/src/any/indirect.rs
+++ b/src/any/indirect.rs
@@ -32,7 +32,9 @@ pub(super) mod sealed {
/// `value` must have been created by `Self::into_raw`.
/// This function must not be called twice for the same `value`.
/// The type `T` must be the one given to `Self::into_raw`.
- unsafe fn from_raw<T: ?Sized + 'a>(value: MaybeUninit<[u8; INDIRECT_SIZE]>) -> Self::ForT<T>;
+ unsafe fn from_raw<T: ?Sized + 'a>(
+ value: MaybeUninit<[u8; INDIRECT_SIZE]>,
+ ) -> Self::ForT<T>;
}
/// An opaque set of bytes the size of a fat pointer.
@@ -42,7 +44,7 @@ pub(super) mod sealed {
pub struct RawIndirect<'a, I> {
indirect: MaybeUninit<[u8; INDIRECT_SIZE]>,
_lifetime: Invariant<'a>,
- _generic: Marker<I>
+ _generic: Marker<I>,
}
impl<'a, I: Indirect<'a>> RawIndirect<'a, I> {
@@ -50,7 +52,7 @@ pub(super) mod sealed {
Self {
indirect: I::into_raw(indirect),
_lifetime: Default::default(),
- _generic: Default::default()
+ _generic: Default::default(),
}
}
@@ -62,9 +64,7 @@ pub(super) mod sealed {
// this type is not clone or copy.
// The caller makes sure that the T is the same.
// Also the lifetime 'a must be the same because Self is invariant over it.
- unsafe {
- I::from_raw(self.indirect)
- }
+ unsafe { I::from_raw(self.indirect) }
}
}
@@ -76,20 +76,20 @@ pub(super) mod sealed {
fn run(&self);
}
- const _: () =
- assert!(core::mem::size_of::<&dyn Helper>() <= core::mem::size_of::<RawIndirect<'_, Ref>>());
+ const _: () = assert!(
+ core::mem::size_of::<&dyn Helper>() <= core::mem::size_of::<RawIndirect<'_, Ref>>()
+ );
// Borrow doesn't need to be dropped.
- const _: () =
- assert!(!core::mem::needs_drop::<&i32>());
+ const _: () = assert!(!core::mem::needs_drop::<&i32>());
const _: () = assert!(
- core::mem::size_of::<&mut dyn Helper>() <= core::mem::size_of::<sealed::RawIndirect<'_, Mut>>()
+ core::mem::size_of::<&mut dyn Helper>()
+ <= core::mem::size_of::<sealed::RawIndirect<'_, Mut>>()
);
// Mutable borrow doesn't need to be dropped.
- const _: () =
- assert!(!core::mem::needs_drop::<&mut i32>());
+ const _: () = assert!(!core::mem::needs_drop::<&mut i32>());
impl<'a> Sealed<'a> for Ref {
fn into_raw<T: ?Sized + 'a>(value: Self::ForT<T>) -> MaybeUninit<[u8; INDIRECT_SIZE]> {
@@ -171,7 +171,7 @@ mod test {
let x = 42;
let y: &i32 = &x;
let z = RawIndirect::<Ref>::new(y);
-
+
// SAFETY: Same type as y which we made it from.
let w: &i32 = unsafe { z.into_inner() };
@@ -231,7 +231,7 @@ mod test {
// SAFETY: Same type as y which we made it from.
let w: &mut dyn AddOne = unsafe { z.into_inner() };
-
+
w.add_one();
assert_eq!(x, 43);
diff --git a/src/any/static_wrapper.rs b/src/any/static_wrapper.rs
index c99b037..d8c22db 100644
--- a/src/any/static_wrapper.rs
+++ b/src/any/static_wrapper.rs
@@ -8,8 +8,7 @@ use super::*;
pub struct OwnedStatic<T: ?Sized>(pub T);
bijective_higher_ranked_type! {
- /// Higher ranked type for [`OwnedStatic`].
- pub for['ctx] type DynOwnedStatic[][T]: WithContextLt['ctx][]
+ for['ctx] use OwnedStatic[][T]: WithContextLt['ctx][]
for<'a>
(OwnedStatic<T>)
where {
@@ -18,9 +17,9 @@ bijective_higher_ranked_type! {
}
bijective_higher_ranked_type! {
- pub type [][T][]: TypeName[][]
+ use OwnedStatic[][T][]: TypeName[][]
for<'ctx>
- (DynOwnedStatic<T>)
+ (OwnedStatic<T>)
where {
T: ?Sized + 'static
}
@@ -31,8 +30,7 @@ bijective_higher_ranked_type! {
pub struct BorrowedStatic<'ctx, T: ?Sized>(pub &'ctx T);
bijective_higher_ranked_type! {
- /// Higher ranked type for [`BorrowedStatic`].
- pub type DynBorrowedStatic['ctx][T]: WithContextLt['ctx][]
+ use BorrowedStatic['ctx][T]: WithContextLt['ctx][]
for<'a>
(BorrowedStatic<'ctx, T>)
where {
@@ -43,7 +41,7 @@ bijective_higher_ranked_type! {
bijective_higher_ranked_type! {
pub type [][T][]: TypeName[][]
for<'ctx>
- (DynBorrowedStatic<'ctx, T>)
+ (BorrowedStatic<'ctx, T>)
where {
T: ?Sized + 'static
}
@@ -54,8 +52,7 @@ bijective_higher_ranked_type! {
pub struct TempBorrowedStatic<'a, T: ?Sized>(pub &'a T);
bijective_higher_ranked_type! {
- /// Higher ranked type for [`TempBorrowedStatic`].
- pub type DynTempBorrowedStatic['ctx][T]: WithContextLt['ctx][]
+ use TempBorrowedStatic['ctx][T]: WithContextLt['ctx][]
for<'a>
(TempBorrowedStatic<'a, T>)
where {
@@ -64,9 +61,9 @@ bijective_higher_ranked_type! {
}
bijective_higher_ranked_type! {
- pub type [][T][]: TypeName[][]
+ pub type [][T]: TypeName[][]
for<'ctx>
- (DynTempBorrowedStatic<'ctx, T>)
+ (TempBorrowedStatic<'ctx, T>)
where {
T: ?Sized + 'static
}
@@ -77,8 +74,7 @@ bijective_higher_ranked_type! {
pub struct BorrowedMutStatic<'ctx, T: ?Sized>(pub &'ctx mut T);
bijective_higher_ranked_type! {
- /// Higher ranked type for [`BorrowedMutStatic`].
- pub type DynBorrowedMutStatic['ctx][T]: WithContextLt['ctx][]
+ use BorrowedMutStatic['ctx][T]: WithContextLt['ctx][]
for<'a>
(BorrowedMutStatic<'ctx, T>)
where {
@@ -89,7 +85,7 @@ bijective_higher_ranked_type! {
bijective_higher_ranked_type! {
pub type [][T][]: TypeName[][]
for<'ctx>
- (DynBorrowedMutStatic<'ctx, T>)
+ (BorrowedMutStatic<'ctx, T>)
where {
T: ?Sized + 'static
}
@@ -100,8 +96,7 @@ bijective_higher_ranked_type! {
pub struct TempBorrowedMutStatic<'a, T: ?Sized>(pub &'a mut T);
bijective_higher_ranked_type! {
- /// Higher ranked type for [`TempBorrowedMutStatic`].
- pub type DynTempBorrowedMutStatic['ctx][T]: WithContextLt['ctx][]
+ use TempBorrowedMutStatic['ctx][T]: WithContextLt['ctx][]
for<'a>
(TempBorrowedMutStatic<'a, T>)
where {
@@ -110,9 +105,9 @@ bijective_higher_ranked_type! {
}
bijective_higher_ranked_type! {
- pub type [][T][]: TypeName[][]
+ pub type[][T][]: TypeName[][]
for<'ctx>
- (DynTempBorrowedMutStatic<'ctx, T>)
+ (TempBorrowedMutStatic<'ctx, T>)
where {
T: ?Sized + 'static
}
@@ -125,8 +120,7 @@ pub struct BoxedStatic<T: ?Sized>(pub Box<T>);
#[cfg(feature = "alloc")]
bijective_higher_ranked_type! {
- /// Higher ranked type for [`BoxedStatic`].
- pub for['ctx] type DynBoxedStatic[][T]: WithContextLt['ctx][]
+ for['ctx] use BoxedStatic[][T]: WithContextLt['ctx][]
for<'a>
(BoxedStatic<T>)
where {
@@ -136,9 +130,9 @@ bijective_higher_ranked_type! {
#[cfg(feature = "alloc")]
bijective_higher_ranked_type! {
- pub type [][T][]: TypeName[][]
+ use BoxedStatic [][T][]: TypeName[][]
for<'ctx>
- (DynBoxedStatic<T>)
+ (BoxedStatic<T>)
where {
T: ?Sized + 'static
}
diff --git a/src/any/type_name_id.rs b/src/any/type_name_id.rs
index 2ba7ffc..1b173f8 100644
--- a/src/any/type_name_id.rs
+++ b/src/any/type_name_id.rs
@@ -121,7 +121,7 @@ mod test {
T: 'ctx
}
}
-
+
bijective_higher_ranked_type! {
type NameExample[][T][]: TypeName[][]
for<'ctx>
diff --git a/src/build.rs b/src/build.rs
index d77bb39..f4476f0 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -26,7 +26,7 @@ pub trait BuilderTypes {
/// The `'ctx` lifetime is some lifetime that is longer than the walker.
/// As such, the built value can borrow from other data with a `'ctx` lifetimes.
///
-/// A builder allows creating a value of a type [`Self::Value`].
+/// A builder allows creating a value of a type [`Self::Value`][BuilderTypes::Value].
/// The way to use a builder is as follows.
/// - Call [`Default::default()`] to create an instance of the builder.
/// - Call [`Self::as_visitor()`] and give it to a walker's
diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs
index fd41ed6..b48b731 100644
--- a/src/build/builders/core/bool.rs
+++ b/src/build/builders/core/bool.rs
@@ -1,11 +1,11 @@
use core::marker::PhantomData;
use crate::{
- any::static_wrapper::{DynOwnedStatic, OwnedStatic},
+ any::OwnedStatic,
any_trait,
effect::{Effect, Future},
protocol::{
- visitor::value::{DynValue, Value},
+ visitor::{DynValue, Value, VisitResult},
Visitor,
},
Flow,
@@ -61,17 +61,20 @@ impl<'ctx, E: Effect> crate::Builder<'ctx, E> for Builder<E> {
any_trait! {
impl['ctx, E] Builder<E> = [
- DynValue<'ctx, DynOwnedStatic<bool>, E>,
+ DynValue<'ctx, OwnedStatic<bool>, E>,
] where E: Effect
}
-impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<bool>, E> for Builder<E> {
+impl<'ctx, E: Effect> Value<'ctx, OwnedStatic<bool>, E> for Builder<E> {
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, Flow, E>
+ fn visit<'a>(
+ &'a mut self,
+ OwnedStatic(value): OwnedStatic<bool>,
+ ) -> Future<'a, VisitResult<OwnedStatic<bool>>, E>
where
- 'ctx: 'a
+ 'ctx: 'a,
{
self.0 = Some(value);
- E::ready(Flow::Continue)
+ E::ready(Flow::Continue.into())
}
}
diff --git a/src/build/builders/debug.rs b/src/build/builders/debug.rs
index 68d9de6..17749dc 100644
--- a/src/build/builders/debug.rs
+++ b/src/build/builders/debug.rs
@@ -1,17 +1,15 @@
use core::{any::TypeId, marker::PhantomData};
use crate::{
- any::static_wrapper::{DynOwnedStatic, OwnedStatic},
+ any::OwnedStatic,
any_trait,
effect::{Effect, Future},
+ protocol::Walker,
protocol::{
self,
visitor::{
- request_hint::{DynRequestHint, RequestHint},
- sequence::{DynSequence, Sequence},
- tag::{DynTag, Tag, TagDyn},
- value::{DynValue, Value},
- Status,
+ DynRequestHint, DynSequence, DynSequenceScope, DynTag, DynValue, RequestHint, Sequence,
+ Tag, TagDyn, Value, VisitResult,
},
},
DynWalker, Flow,
@@ -24,10 +22,10 @@ any_trait! {
DynRequestHint<'ctx, E>,
// DynRecoverable<'a, 'ctx, E>,
DynTag<'ctx, TagDyn, E>,
- DynValue<'ctx, DynOwnedStatic<&'static str>, E>,
- DynValue<'ctx, DynOwnedStatic<TypeId>, E>,
- DynValue<'ctx, DynOwnedStatic<usize>, E>,
- DynValue<'ctx, DynOwnedStatic<bool>, E>,
+ DynValue<'ctx, OwnedStatic<&'static str>, E>,
+ DynValue<'ctx, OwnedStatic<TypeId>, E>,
+ DynValue<'ctx, OwnedStatic<usize>, E>,
+ DynValue<'ctx, OwnedStatic<bool>, E>,
// DynValue<'a, 'ctx, OwnedStatic<&'static [&'static str]>, E>,
DynSequence<'ctx, E>,
] else {
@@ -61,12 +59,12 @@ impl<E: Effect> Visitor<E> {
impl<'ctx, E: Effect> RequestHint<'ctx, E> for Visitor<E> {
fn request_hint<'a>(
&'a mut self,
- _walker: crate::protocol::Walker<'a, 'ctx>,
- ) -> Future<'a, Flow, E> {
+ _walker: Walker<'a, 'ctx>,
+ ) -> Future<'a, VisitResult<Walker<'a, 'ctx>>, E> {
// self.tab();
// println!("Visit request hint (no hint given)");
// println!("Visit request hint (hint for recoverable)");
- E::ready(Flow::Continue)
+ E::ready(Flow::Continue.into())
}
}
@@ -75,7 +73,7 @@ impl<'ctx, E: Effect> Tag<'ctx, TagDyn, E> for Visitor<E> {
&'a mut self,
kind: TagDyn,
walker: DynWalker<'a, 'ctx, E>,
- ) -> Future<'a, Status, E> {
+ ) -> Future<'a, VisitResult<DynWalker<'a, 'ctx, E>>, E> {
E::wrap(async move {
match kind.0 {
crate::TAG_TYPE_NAME => {
@@ -86,7 +84,7 @@ impl<'ctx, E: Effect> Tag<'ctx, TagDyn, E> for Visitor<E> {
let _ = walker.walk(self).await;
self.0 -= 1;
- Status::r#continue()
+ Flow::Continue.into()
}
crate::TAG_KEY => {
self.tab();
@@ -96,7 +94,7 @@ impl<'ctx, E: Effect> Tag<'ctx, TagDyn, E> for Visitor<E> {
let _ = walker.walk(self).await;
self.0 -= 1;
- Status::r#continue()
+ Flow::Continue.into()
}
crate::TAG_VALUE => {
self.tab();
@@ -106,79 +104,89 @@ impl<'ctx, E: Effect> Tag<'ctx, TagDyn, E> for Visitor<E> {
let _ = walker.walk(self).await;
self.0 -= 1;
- Status::r#continue()
+ Flow::Continue.into()
}
- _ => Status::skipped(),
+ _ => VisitResult::Skipped(walker),
}
})
}
}
-impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<&'static str>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, OwnedStatic<&'static str>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<&'static str>,
- ) -> Future<'a, Flow, E>
+ ) -> Future<'a, VisitResult<OwnedStatic<&'static str>>, E>
where
- 'ctx: 'a
+ 'ctx: 'a,
{
self.tab();
println!("{:?}", value);
- E::ready(Flow::Continue)
+ E::ready(Flow::Continue.into())
}
}
-impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<usize>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, OwnedStatic<usize>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<usize>,
- ) -> Future<'a, Flow, E>
+ ) -> Future<'a, VisitResult<OwnedStatic<usize>>, E>
where
- 'ctx: 'a {
+ 'ctx: 'a,
+ {
self.tab();
println!("{}", value);
- E::ready(Flow::Continue)
+ E::ready(Flow::Continue.into())
}
}
-impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<bool>, E> for Visitor<E> {
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, Flow, E>
- where 'ctx: 'a{
+impl<'ctx, E: Effect> Value<'ctx, OwnedStatic<bool>, E> for Visitor<E> {
+ fn visit<'a>(
+ &'a mut self,
+ OwnedStatic(value): OwnedStatic<bool>,
+ ) -> Future<'a, VisitResult<OwnedStatic<bool>>, E>
+ where
+ 'ctx: 'a,
+ {
self.tab();
println!("{}", value);
- E::ready(Flow::Continue)
+ E::ready(Flow::Continue.into())
}
}
-impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<&'static [&'static str]>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, OwnedStatic<&'static [&'static str]>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<&'static [&'static str]>,
- ) -> Future<'a, Flow, E>
- where 'ctx: 'a{
+ ) -> Future<'a, VisitResult<OwnedStatic<&'static [&'static str]>>, E>
+ where
+ 'ctx: 'a,
+ {
self.tab();
println!("{:?}", value);
- E::ready(Flow::Continue)
+ E::ready(Flow::Continue.into())
}
}
-impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<TypeId>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, OwnedStatic<TypeId>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<TypeId>,
- ) -> Future<'a, Flow, E>
- where 'ctx: 'a{
+ ) -> Future<'a, VisitResult<OwnedStatic<TypeId>>, E>
+ where
+ 'ctx: 'a,
+ {
self.tab();
println!("Visit type ID: {:?}", value);
- E::ready(Flow::Continue)
+ E::ready(Flow::Continue.into())
}
}
impl<'ctx, E: Effect> Sequence<'ctx, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
- scope: protocol::visitor::sequence::DynSequenceScope<'a, 'ctx, E>,
- ) -> Future<'a, Flow, E> {
+ scope: protocol::visitor::DynSequenceScope<'a, 'ctx, E>,
+ ) -> Future<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E> {
E::wrap(async {
self.tab();
println!("sequence{:?}", scope.size_hint().await);
@@ -198,13 +206,13 @@ impl<'ctx, E: Effect> Sequence<'ctx, E> for Visitor<E> {
break Flow::Continue;
}
Flow::Continue => {}
- Flow::Break => break Flow::Break,
+ Flow::Err => break Flow::Err,
}
index += 1;
self.0 -= 1;
};
self.0 -= 2;
- flow
+ flow.into()
})
}
}
diff --git a/src/effect.rs b/src/effect.rs
index 71e4aec..b50b37a 100644
--- a/src/effect.rs
+++ b/src/effect.rs
@@ -5,7 +5,7 @@ use core::{
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
-use crate::{bijective_higher_ranked_type, bijective_higher_ranked_trait};
+use crate::{bijective_higher_ranked_trait, bijective_higher_ranked_type};
bijective_higher_ranked_trait! {
pub type class SendFuture[][Output]: [for<'lt> core::future::Future<Output = Output> + Sized + Send + 'lt]
diff --git a/src/hkt.rs b/src/hkt.rs
index f51ebed..8cc3952 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -10,12 +10,12 @@
//! lifetime. Sadly, Rust only allows `for<'a>` in trait objects. However, trait object provide
//! enough for us to implement arbitrary hifher-ranked types with some extra effort.
//!
-//! In this module the [`higher_ranked_type!`] macro generates a type that needs a lifetime to
+//! In this module the [`bijective_higher_ranked_type!`] macro generates a type that needs a lifetime to
//! be complete. Before a higher-ranked type can be generated we need a higher-ranked trait to
//! describe what behavior the resulting "true" type will have.
//!
-//! The [`higher_ranked_trait!`] macro cgenerates a trait that can be used with
-//! [`higher_ranked_type!`] and as a bound by code wanting to accept a higher ranked type.
+//! The [`bijective_higher_ranked_trait!`] macro cgenerates a trait that can be used with
+//! [`bijective_higher_ranked_type!`] and as a bound by code wanting to accept a higher ranked type.
//! Bounding a generic by a higher-ranked trait simultaniously allows any higher-ranked type with
//! a "true" type with the required traits and any lifetime to be given to that "true" type.
@@ -74,7 +74,13 @@ macro_rules! bijective_higher_ranked_trait {
/// type alias.
///
/// This acts to inject a lifetime into the higher ranked type to make it concrete.
- pub trait LowerForLt<$lt, $($lifetimes: $lt,)* B: $lt, $($generic: $lt),*> $(: $($self_provides)*)?
+ pub trait LowerForLt<
+ $lt,
+ $($lifetimes: $lt,)*
+ B: $lt,
+ $($generic: $lt),*
+ >
+ $(: $($self_provides)*)?
where
$($($bound)*)?
$($($for_bound)*)?
@@ -221,8 +227,7 @@ pub use bijective_higher_ranked_trait;
#[macro_export]
macro_rules! bijective_higher_ranked_type {
{
- $(#[$($meta:tt)*])*
- $vis:vis $(for[$($extra_lt:lifetime)*])? type $name:ident[
+ $(for[$($extra_lt:lifetime)*])? use $name:ident[
$($ctx:lifetime),*
][
$($generic:ident),*
@@ -234,19 +239,6 @@ macro_rules! bijective_higher_ranked_type {
($higher_ranked_type:ty)
$(where {$($bound:tt)*})?
} => {
- $(#[$($meta)*])*
- $vis struct $name<
- $($ctx,)*
- $($generic: ?Sized,)*
- $($($forwarding_generic: ?Sized),*)?
- >(
- core::marker::PhantomData<fn() -> (
- $(&$ctx (),)*
- $(*const $generic,)*
- $($(*const $forwarding_generic,)*)?
- )>
- );
-
impl<
$lt,
$($($extra_lt,)*)?
@@ -330,6 +322,47 @@ macro_rules! bijective_higher_ranked_type {
}
};
{
+ $(#[$($meta:tt)*])*
+ $vis:vis $(for[$($extra_lt:lifetime)*])? type $name:ident[
+ $($ctx:lifetime),*
+ ][
+ $($generic:ident),*
+ ]$([
+ $($forwarding_generic:ident[$($forward_lt:lifetime),*][$($forward_generic:ident),*]),*
+ ])?: $type_class:ident[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
+ for<$lt:lifetime>
+ ($for_lt_type:ty)
+ ($higher_ranked_type:ty)
+ $(where {$($bound:tt)*})?
+ } => {
+ $(#[$($meta)*])*
+ $vis struct $name<
+ $($ctx,)*
+ $($generic: ?Sized,)*
+ $($($forwarding_generic: ?Sized),*)?
+ >(
+ core::marker::PhantomData<fn() -> (
+ $(&$ctx (),)*
+ $(*const $generic,)*
+ $($(*const $forwarding_generic,)*)?
+ )>
+ );
+
+ $crate::hkt::bijective_higher_ranked_type! {
+ $(for[$($extra_lt)*])? use $name[
+ $($ctx),*
+ ][
+ $($generic),*
+ ]$([
+ $($forwarding_generic[$($forward_lt),*][$($forward_generic),*]),*
+ ])?: $type_class[$($type_class_lifetime)*][$($type_class_generic)*]
+ for<$lt>
+ ($for_lt_type)
+ ($higher_ranked_type)
+ $(where {$($bound)*})?
+ }
+ };
+ {
$vis:vis $(for[$($extra_lt:lifetime)*])? type [
$($ctx:lifetime),*
][
@@ -385,6 +418,32 @@ macro_rules! bijective_higher_ranked_type {
($for_lt_type)
$(where {$($bound)*})?
}
+ };
+ {
+ $(for[$($extra_lt:lifetime)*])? use $name:ident[
+ $($ctx:lifetime),*
+ ][
+ $($generic:ident),*
+ ]$([
+ $($forwarding_generic:ident[$($forward_lt:lifetime),*][$($forward_generic:ident),*]),*
+ ])?: $type_class:ident[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
+ for<$lt:lifetime>
+ ($for_lt_type:ty)
+ $(where {$($bound:tt)*})?
+ } => {
+ $crate::hkt::bijective_higher_ranked_type! {
+ $(for[$($extra_lt)*])? use $name[
+ $($ctx),*
+ ][
+ $($generic),*
+ ]$([
+ $($forwarding_generic[$($forward_lt),*][$($forward_generic),*]),*
+ ])?: $type_class[$($type_class_lifetime)*][$($type_class_generic)*]
+ for<$lt>
+ ($for_lt_type)
+ ($for_lt_type)
+ $(where {$($bound)*})?
+ }
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 21f642c..4a37b96 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,11 +11,11 @@ pub mod any;
mod build;
pub mod effect;
pub mod hkt;
+pub mod macros;
pub mod protocol;
pub mod symbol;
mod transform;
mod walk;
-pub mod macros;
pub use build::*;
pub use transform::*;
@@ -55,18 +55,15 @@ pub const TAG_ENUM: Symbol = Symbol::new("Enum");
pub enum DefaultMode {}
+pub type Status = Result<(), ()>;
+
#[derive(Clone, Copy, PartialEq, Debug)]
#[must_use]
pub enum Flow {
- /// Processing should continue as normal.
Continue,
- /// Processing should stop.
- ///
- /// This state signals some error happened.
- Break,
+ Err,
- /// Processing should stop.
Done,
}
@@ -129,7 +126,7 @@ macro_rules! Walk {
let value_walker = <&'ctx $type as $crate::Walk::<'ctx, M, E>>::into_walker(&value.$field);
- let walker = $crate::walkers::core::key_value::KeyValueWalker::<$crate::protocol::visitor::tag::TagConst<{ $crate::TAG_FIELD.to_int() }>, _, _>::new($crate::protocol::visitor::tag::TagConst, key_walker, value_walker);
+ 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(_) => {
diff --git a/src/protocol/visitor.rs b/src/protocol/visitor.rs
index af82045..fd8d8cd 100644
--- a/src/protocol/visitor.rs
+++ b/src/protocol/visitor.rs
@@ -1,41 +1,31 @@
use crate::Flow;
-pub mod recoverable;
-pub mod request_hint;
-pub mod sequence;
-pub mod tag;
-pub mod value;
+mod recoverable;
+mod request_hint;
+mod sequence;
+mod tag;
+mod value;
+
+pub use recoverable::*;
+pub use request_hint::*;
+pub use sequence::*;
+pub use tag::*;
+pub use value::*;
#[derive(Debug)]
-pub enum Status<S = ()> {
+pub enum VisitResult<S> {
/// The protocol was not used.
+ ///
+ /// This either means the visitor doesn't support the protocol at all, or
+ /// it didn't want to use the protocol right now.
Skipped(S),
- Flow(Flow),
+ /// How control flow should proceed.
+ Control(Flow),
}
-impl<S> Status<S> {
- pub fn r#continue() -> Self {
- Self::Flow(Flow::Continue)
- }
-
- pub fn done() -> Self {
- Self::Flow(Flow::Done)
- }
-
- pub fn r#break() -> Self {
- Self::Flow(Flow::Break)
- }
-}
-
-impl Status {
- pub fn skipped() -> Self {
- Self::Skipped(())
- }
-}
-
-impl From<Flow> for Status {
+impl<S> From<Flow> for VisitResult<S> {
fn from(value: Flow) -> Self {
- Status::Flow(value)
+ Self::Control(value)
}
}
diff --git a/src/protocol/visitor/recoverable.rs b/src/protocol/visitor/recoverable.rs
index 90c671b..e23c69e 100644
--- a/src/protocol/visitor/recoverable.rs
+++ b/src/protocol/visitor/recoverable.rs
@@ -1,14 +1,19 @@
use crate::{
- any::{TypeName, WithContextLt}, bijective_higher_ranked_type, effect::{Effect, Future}, hkt::AnySizedSend, protocol::{walker::hint::HintMeta, Visitor}, Flow
+ any::{TypeName, WithContextLt},
+ bijective_higher_ranked_type,
+ effect::{Effect, Future},
+ hkt::AnySizedSend,
+ protocol::{walker::hint::HintMeta, Visitor},
+ Status,
};
-use super::Status;
+use super::VisitResult;
pub trait Recoverable<'ctx, E: Effect> {
fn visit<'a>(
&'a mut self,
scope: DynRecoverableScope<'a, 'ctx, E>,
- ) -> Future<'a, Flow, E>;
+ ) -> Future<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E>;
}
bijective_higher_ranked_type! {
@@ -30,7 +35,7 @@ bijective_higher_ranked_type! {
}
pub trait RecoverableScope<'ctx, E: Effect> {
- fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E>;
+ fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Status, E>;
}
pub type DynRecoverableScope<'a, 'ctx, E> = &'a mut (dyn RecoverableScope<'ctx, E> + Send + 'a);
@@ -48,23 +53,12 @@ impl<'ctx, E: Effect> HintMeta<'ctx> for DynRecoverable<'ctx, E> {
pub fn visit_recoverable<'a, 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
scope: DynRecoverableScope<'a, 'ctx, E>,
-) -> Future<'a, Status, E> {
+) -> Future<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E> {
if let Some(object) = visitor.upcast_mut::<DynRecoverable<'ctx, E>>() {
// Allow the visitor to give a hint if it wants.
- E::map(object.visit(scope), |flow| match flow {
- Flow::Continue => {
- // The visitor wants the walker to continue to it's normal
- // walking.
- Status::r#continue()
- }
- Flow::Break | Flow::Done => {
- // The visitor is done (either because of an error or because
- // it already used a hint).
- Status::r#break()
- }
- })
+ object.visit(scope)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(Status::skipped())
+ E::ready(VisitResult::Skipped(scope))
}
}
diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs
index 343dcb9..8b4f573 100644
--- a/src/protocol/visitor/request_hint.rs
+++ b/src/protocol/visitor/request_hint.rs
@@ -3,16 +3,20 @@ use crate::{
bijective_higher_ranked_type,
effect::{Effect, Future},
protocol::{Visitor, Walker},
- Flow,
};
+use super::VisitResult;
+
/// Protocol for requesting a hint from a visitor.
pub trait RequestHint<'ctx, E: Effect> {
/// 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>(&'a mut self, walker: Walker<'a, 'ctx>) -> Future<'a, Flow, E>;
+ fn request_hint<'a>(
+ &'a mut self,
+ walker: Walker<'a, 'ctx>,
+ ) -> Future<'a, VisitResult<Walker<'a, 'ctx>>, E>;
}
bijective_higher_ranked_type! {
@@ -43,12 +47,12 @@ bijective_higher_ranked_type! {
pub fn visit_request_hint<'a, 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
walker: Walker<'a, 'ctx>,
-) -> Future<'a, Flow, E> {
+) -> Future<'a, VisitResult<Walker<'a, 'ctx>>, E> {
if let Some(object) = visitor.upcast_mut::<DynRequestHint<'ctx, E>>() {
// Allow the visitor to give a hint if it wants.
object.request_hint(walker)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(Flow::Continue)
+ E::ready(VisitResult::Skipped(walker))
}
}
diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs
index 25ba8dd..23bc3ce 100644
--- a/src/protocol/visitor/sequence.rs
+++ b/src/protocol/visitor/sequence.rs
@@ -7,10 +7,13 @@ use crate::{
Flow,
};
-use super::Status;
+use super::VisitResult;
pub trait Sequence<'ctx, E: Effect> {
- fn visit<'a>(&'a mut self, scope: DynSequenceScope<'a, 'ctx, E>) -> Future<'a, Flow, E>;
+ fn visit<'a>(
+ &'a mut self,
+ scope: DynSequenceScope<'a, 'ctx, E>,
+ ) -> Future<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E>;
}
bijective_higher_ranked_type! {
@@ -61,23 +64,12 @@ impl<'ctx, E: Effect> HintMeta<'ctx> for DynSequence<'ctx, E> {
pub fn visit_sequence<'a, 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
scope: DynSequenceScope<'a, 'ctx, E>,
-) -> Future<'a, Status, E> {
+) -> Future<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E> {
if let Some(object) = visitor.upcast_mut::<DynSequence<'ctx, E>>() {
// Allow the visitor to give a hint if it wants.
- E::map(object.visit(scope), |flow| match flow {
- Flow::Continue => {
- // The visitor wants the walker to continue to it's normal
- // walking.
- Status::r#continue()
- }
- Flow::Break | Flow::Done => {
- // The visitor is done (either because of an error or because
- // it already used a hint).
- Status::r#break()
- }
- })
+ object.visit(scope)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(Status::skipped())
+ E::ready(VisitResult::Skipped(scope))
}
}
diff --git a/src/protocol/visitor/tag.rs b/src/protocol/visitor/tag.rs
index 4d0bfb2..d6cf1ae 100644
--- a/src/protocol/visitor/tag.rs
+++ b/src/protocol/visitor/tag.rs
@@ -5,14 +5,12 @@ use crate::{
hkt::AnySizedSend,
protocol::{walker::hint::HintMeta, Visitor},
symbol::Symbol,
- DynWalker, DynWalkerAdapter, DynWalkerError, Flow, WalkerTypes,
+ DynWalker, DynWalkerAdapter, DynWalkerError, WalkerTypes,
};
-use super::Status;
+use super::VisitResult;
pub trait TagKind: Copy + Send + 'static {
- type Flow: Send + Into<Status>;
-
fn symbol(&self) -> Symbol;
}
@@ -23,16 +21,12 @@ pub struct TagConst<const SYMBOL: u64>;
pub struct TagDyn(pub Symbol);
impl<const SYMBOL: u64> TagKind for TagConst<SYMBOL> {
- type Flow = Flow;
-
fn symbol(&self) -> Symbol {
Symbol::from_int(SYMBOL)
}
}
impl TagKind for TagDyn {
- type Flow = Status;
-
fn symbol(&self) -> Symbol {
self.0
}
@@ -43,7 +37,7 @@ pub trait Tag<'ctx, K: TagKind, E: Effect> {
&'a mut self,
kind: K,
walker: DynWalker<'a, 'ctx, E>,
- ) -> Future<'a, K::Flow, E>;
+ ) -> Future<'a, VisitResult<DynWalker<'a, 'ctx, E>>, E>;
}
bijective_higher_ranked_type! {
@@ -138,21 +132,19 @@ pub fn visit_tag<'a, 'ctx: 'a, K: TagKind, E: Effect, W: crate::Walker<'ctx, E>
kind: K,
visitor: Visitor<'a, 'ctx>,
walker: W,
-) -> Future<'a, Result<Status<W>, TagError<W::Error>>, E>
+) -> Future<'a, Result<VisitResult<W>, TagError<W::Error>>, E>
where
W: WalkerTypes,
{
+ // Wrap the walker to allow it to be passed to a dyn walker argument.
+ let mut walker = DynWalkerAdapter::new(walker);
+
E::wrap(async move {
- let (flow, walker) = if let Some(object) = visitor.upcast_mut::<DynTag<'ctx, K, E>>() {
+ let result = if let Some(object) = visitor.upcast_mut::<DynTag<'ctx, K, E>>() {
// The visitor knows about this tag.
- // Wrap the walker to allow it to be passed to a dyn walker argument.
- let mut walker = DynWalkerAdapter::new(walker);
-
// Visit the tag.
- let flow = object.visit(kind, &mut walker).await;
-
- (flow.into(), walker)
+ object.visit(kind, &mut walker).await
} else if core::any::TypeId::of::<TagDyn>() != core::any::TypeId::of::<K>() {
// Try the dynamic form if we didn't already.
if let Some(object) = visitor.upcast_mut::<DynTag<'ctx, TagDyn, E>>() {
@@ -160,36 +152,43 @@ where
// If the visitor can't handle the tag kind then it can call .skip on the walker
// to disable the error for not walking it.
- // Wrap the walker to allow it to be passed to a dyn walker argument.
- let mut walker = DynWalkerAdapter::new(walker);
-
// Visit the tag.
- let flow = object.visit(TagDyn(kind.symbol()), &mut walker).await;
-
- (flow, walker)
+ object.visit(TagDyn(kind.symbol()), &mut walker).await
} else {
- return Ok(Status::Skipped(walker));
+ let walker: W = walker
+ .into_innter()
+ .map_err(|err| map_walker_err(kind, err))?;
+ return Ok(VisitResult::Skipped(walker));
}
} else {
- return Ok(Status::Skipped(walker));
+ let walker: W = walker
+ .into_innter()
+ .map_err(|err| map_walker_err(kind, err))?;
+ return Ok(VisitResult::Skipped(walker));
};
- match flow {
+ match result {
// The walker was skipped.
- Status::Skipped(()) => match walker.into_innter() {
- Ok(walker) => Ok(Status::Skipped(walker)),
- Err(DynWalkerError::Walker(err)) => Err(TagError::new(kind, err)),
- Err(DynWalkerError::NeverWalked(_)) => Err(TagError::never_walked(kind)),
- Err(DynWalkerError::WalkNeverFinished) => Err(TagError::walk_never_finished(kind)),
- Err(DynWalkerError::WasWalked(_)) => Err(TagError::was_walked(kind)),
+ VisitResult::Skipped(_) => match walker.into_innter() {
+ Ok(walker) => Ok(VisitResult::Skipped(walker)),
+ Err(err) => Err(map_walker_err(kind, err)),
},
- Status::Flow(flow) => match walker.finish() {
- Ok(_) => Ok(Status::Flow(flow)),
- Err(DynWalkerError::Walker(err)) => Err(TagError::new(kind, err)),
- Err(DynWalkerError::NeverWalked(_)) => Err(TagError::never_walked(kind)),
- Err(DynWalkerError::WalkNeverFinished) => Err(TagError::walk_never_finished(kind)),
- Err(DynWalkerError::WasWalked(_)) => Err(TagError::was_walked(kind)),
+ VisitResult::Control(flow) => match walker.finish() {
+ Ok(_) => Ok(VisitResult::Control(flow)),
+ Err(err) => Err(map_walker_err(kind, err)),
},
}
})
}
+
+fn map_walker_err<K: TagKind, W: WalkerTypes>(
+ kind: K,
+ err: DynWalkerError<W>,
+) -> TagError<W::Error> {
+ match err {
+ DynWalkerError::Walker(err) => TagError::new(kind, err),
+ DynWalkerError::NeverWalked(_) => TagError::never_walked(kind),
+ DynWalkerError::WalkNeverFinished => TagError::walk_never_finished(kind),
+ DynWalkerError::WasWalked(_) => TagError::was_walked(kind),
+ }
+}
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index 43a845f..447ad82 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -8,10 +8,9 @@ use crate::{
effect::{Effect, Future},
hkt::AnySizedSend,
protocol::{walker::hint::HintMeta, Visitor},
- Flow,
};
-use super::Status;
+use super::VisitResult;
/// Trait object for the [`Value`] protocol.
///
@@ -26,8 +25,12 @@ pub trait Value<'ctx, T: WithContextLt::MemberType<'ctx>, E: Effect> {
/// 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: WithContextLt::T<'a, 'ctx, T>) -> Future<'a, Flow, E>
+ fn visit<'a>(
+ &'a mut self,
+ value: WithContextLt::T<'a, 'ctx, T>,
+ ) -> Future<'a, VisitResult<WithContextLt::T<'a, 'ctx, T>>, E>
where
+ WithContextLt::T<'a, 'ctx, T>: Send + Sized,
'ctx: 'a;
}
@@ -65,10 +68,10 @@ impl<'a, 'ctx: 'a, T, E: Effect> HintMeta<'ctx> for DynValue<'ctx, T, E> {
type Hint = ();
}
-pub fn visit_value<'a, 'ctx, T: WithContextLt::LowerType<'a, 'ctx> + 'ctx, E: Effect>(
+pub fn visit_value<'a, 'ctx, T: Send + WithContextLt::LowerType<'a, 'ctx> + 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
value: T,
-) -> Future<'a, Status, E>
+) -> Future<'a, VisitResult<T>, E>
where
WithContextLt::HigherRanked<'a, 'ctx, T>: TypeName::LowerType<'ctx> + Sized,
{
@@ -76,188 +79,174 @@ where
visitor.upcast_mut::<DynValue<'ctx, WithContextLt::HigherRanked<'a, 'ctx, T>, E>>()
{
// Allow the visitor to give a hint if it wants.
- E::map(object.visit(value), |flow| match flow {
- Flow::Continue => {
- // The visitor wants the walker to continue to it's normal
- // walking.
- Status::r#continue()
- }
- Flow::Break | Flow::Done => {
- // The visitor is done (either because of an error or because
- // it already used a hint).
- Status::r#break()
- }
- })
+ object.visit(value)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(Status::skipped())
+ E::ready(VisitResult::Skipped(value))
}
}
-#[cfg(test)]
-mod test {
- use core::marker::PhantomData;
-
- use crate::{
- any::{
- static_wrapper::{
- BorrowedMutStatic, BorrowedStatic, DynBorrowedMutStatic, DynBorrowedStatic,
- DynOwnedStatic, OwnedStatic,
- },
- AnyTrait,
- },
- any_trait,
- effect::{BlockOn, Blocking, Spin},
- };
-
- use super::*;
-
- #[test]
- fn visit() {
- struct Visitor<E>(Option<i32>, PhantomData<fn() -> E>);
-
- impl<'ctx, E> Value<'ctx, DynOwnedStatic<i32>, E> for Visitor<E>
- where
- E: Effect,
- {
- fn visit<'a>(
- &'a mut self,
- OwnedStatic(value): OwnedStatic<i32>,
- ) -> Future<'a, Flow, E>
- where 'ctx: 'a{
- E::wrap(async move {
- self.0 = Some(value);
- Flow::Continue
- })
- }
- }
-
- impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, i32>, E> for Visitor<E>
- where
- E: Effect,
- {
- fn visit<'a>(
- &'a mut self,
- BorrowedStatic(value): BorrowedStatic<'ctx, i32>,
- ) -> Future<'a, Flow, E>
- where
- 'ctx: 'a
- {
- E::wrap(async {
- self.0 = Some(*value);
- Flow::Continue
- })
- }
- }
-
- any_trait! {
- impl['ctx, E] Visitor<E> = [
- DynValue<'ctx, DynOwnedStatic<i32>, E>,
- DynValue<'ctx, DynBorrowedStatic<'ctx, i32>, E>,
- ] where E: Effect,
- }
-
- let mut v = Visitor::<Blocking>(None, PhantomData);
- let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- let _ = Spin::block_on(
- object
- .upcast_mut::<DynValue<'_, DynOwnedStatic<i32>, Blocking>>()
- .unwrap()
- .visit(OwnedStatic(42)),
- );
-
- assert_eq!(v.0, Some(42));
-
- let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- let _ = Spin::block_on(
- object
- .upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, i32>, Blocking>>()
- .unwrap()
- .visit(BorrowedStatic(&101)),
- );
-
- assert_eq!(v.0, Some(101));
- }
-
- #[test]
- fn visit_borrowed() {
- struct Visitor<'ctx, E>(Option<&'ctx mut String>, PhantomData<fn() -> E>);
-
- impl<'ctx, E> Value<'ctx, DynBorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E>
- where
- E: Effect,
- {
- fn visit<'a>(
- &'a mut self,
- BorrowedMutStatic(value): BorrowedMutStatic<'ctx, String>,
- ) -> Future<'a, Flow, E>
- where 'ctx: 'a{
- E::wrap(async {
- self.0 = Some(value);
-
- Flow::Continue
- })
- }
- }
-
- any_trait! {
- impl['ctx, E] Visitor<'ctx, E> = [
- DynValue<'ctx, DynBorrowedMutStatic<'ctx, String>, E>,
- ] where E: Effect
- }
-
- let mut v = Visitor::<Blocking>(None, PhantomData);
-
- let mut y = String::from("abc");
- let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- let _ = Spin::block_on(
- object
- .upcast_mut::<DynValue<'_, DynBorrowedMutStatic<'_, _>, Blocking>>()
- .unwrap()
- .visit(BorrowedMutStatic(&mut y)),
- );
-
- v.0.unwrap().push_str("def");
- assert_eq!(y, "abcdef");
- }
-
- #[test]
- fn visit_borrowed_unsized() {
- struct Visitor<'ctx, E>(Option<&'ctx str>, PhantomData<fn() -> E>);
-
- impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E>
- where
- E: Effect,
- {
- fn visit<'a>(
- &'a mut self,
- BorrowedStatic(value): BorrowedStatic<'ctx, str>,
- ) -> Future<'a, Flow, E>
- where 'ctx: 'a{
- E::wrap(async {
- self.0 = Some(value);
- Flow::Continue
- })
- }
- }
-
- any_trait! {
- impl['ctx, E] Visitor<'ctx, E> = [
- DynValue<'ctx, DynBorrowedStatic<'ctx, str>, E>,
- ] where E: Effect
- }
-
- let mut v = Visitor::<Blocking>(None, PhantomData);
-
- let y = String::from("abc");
- let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- let _ = Spin::block_on(
- object
- .upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, str>, Blocking>>()
- .unwrap()
- .visit(BorrowedStatic(&y)),
- );
-
- assert_eq!(v.0, Some("abc"));
- }
-}
+// #[cfg(test)]
+// mod test {
+// use core::marker::PhantomData;
+//
+// use crate::{
+// any::{AnyTrait, BorrowedMutStatic, BorrowedStatic, OwnedStatic},
+// any_trait,
+// effect::{BlockOn, Blocking, Spin},
+// };
+//
+// use super::*;
+//
+// #[test]
+// fn visit() {
+// struct Visitor<E>(Option<i32>, PhantomData<fn() -> E>);
+//
+// impl<'ctx, E> Value<'ctx, OwnedStatic<i32>, E> for Visitor<E>
+// where
+// E: Effect,
+// {
+// fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<i32>) -> Future<'a, Flow, E>
+// where
+// 'ctx: 'a,
+// {
+// E::wrap(async move {
+// self.0 = Some(value);
+// Flow::Continue
+// })
+// }
+// }
+//
+// impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, i32>, E> for Visitor<E>
+// where
+// E: Effect,
+// {
+// fn visit<'a>(
+// &'a mut self,
+// BorrowedStatic(value): BorrowedStatic<'ctx, i32>,
+// ) -> Future<'a, Flow, E>
+// where
+// 'ctx: 'a,
+// {
+// E::wrap(async {
+// self.0 = Some(*value);
+// Flow::Continue
+// })
+// }
+// }
+//
+// any_trait! {
+// impl['ctx, E] Visitor<E> = [
+// DynValue<'ctx, OwnedStatic<i32>, E>,
+// DynValue<'ctx, BorrowedStatic<'ctx, i32>, E>,
+// ] where E: Effect,
+// }
+//
+// let mut v = Visitor::<Blocking>(None, PhantomData);
+// let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
+// let _ = Spin::block_on(
+// object
+// .upcast_mut::<DynValue<'_, OwnedStatic<i32>, Blocking>>()
+// .unwrap()
+// .visit(OwnedStatic(42)),
+// );
+//
+// assert_eq!(v.0, Some(42));
+//
+// let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
+// let _ = Spin::block_on(
+// object
+// .upcast_mut::<DynValue<'_, BorrowedStatic<'_, i32>, Blocking>>()
+// .unwrap()
+// .visit(BorrowedStatic(&101)),
+// );
+//
+// assert_eq!(v.0, Some(101));
+// }
+//
+// #[test]
+// fn visit_borrowed() {
+// struct Visitor<'ctx, E>(Option<&'ctx mut String>, PhantomData<fn() -> E>);
+//
+// impl<'ctx, E> Value<'ctx, BorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E>
+// where
+// E: Effect,
+// {
+// fn visit<'a>(
+// &'a mut self,
+// BorrowedMutStatic(value): BorrowedMutStatic<'ctx, String>,
+// ) -> Future<'a, Flow, E>
+// where
+// 'ctx: 'a,
+// {
+// E::wrap(async {
+// self.0 = Some(value);
+//
+// Flow::Continue
+// })
+// }
+// }
+//
+// any_trait! {
+// impl['ctx, E] Visitor<'ctx, E> = [
+// DynValue<'ctx, BorrowedMutStatic<'ctx, String>, E>,
+// ] where E: Effect
+// }
+//
+// let mut v = Visitor::<Blocking>(None, PhantomData);
+//
+// let mut y = String::from("abc");
+// let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
+// let _ = Spin::block_on(
+// object
+// .upcast_mut::<DynValue<'_, BorrowedMutStatic<'_, _>, Blocking>>()
+// .unwrap()
+// .visit(BorrowedMutStatic(&mut y)),
+// );
+//
+// v.0.unwrap().push_str("def");
+// assert_eq!(y, "abcdef");
+// }
+//
+// #[test]
+// fn visit_borrowed_unsized() {
+// struct Visitor<'ctx, E>(Option<&'ctx str>, PhantomData<fn() -> E>);
+//
+// impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E>
+// where
+// E: Effect,
+// {
+// fn visit<'a>(
+// &'a mut self,
+// BorrowedStatic(value): BorrowedStatic<'ctx, str>,
+// ) -> Future<'a, Flow, E>
+// where
+// 'ctx: 'a,
+// {
+// E::wrap(async {
+// self.0 = Some(value);
+// Flow::Continue
+// })
+// }
+// }
+//
+// any_trait! {
+// impl['ctx, E] Visitor<'ctx, E> = [
+// DynValue<'ctx, BorrowedStatic<'ctx, str>, E>,
+// ] where E: Effect
+// }
+//
+// let mut v = Visitor::<Blocking>(None, PhantomData);
+//
+// let y = String::from("abc");
+// let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
+// let _ = Spin::block_on(
+// object
+// .upcast_mut::<DynValue<'_, BorrowedStatic<'_, str>, Blocking>>()
+// .unwrap()
+// .visit(BorrowedStatic(&y)),
+// );
+//
+// assert_eq!(v.0, Some("abc"));
+// }
+// }
diff --git a/src/walk.rs b/src/walk.rs
index 672bfd3..5bdd5ec 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -122,7 +122,7 @@ impl<'ctx, W: Walker<'ctx, E>, E: Effect> WalkerObjSafe<'ctx, E> for DynWalkerAd
// Signal that control flow should stop as soon as possible as we
// are in an error state.
- Flow::Break
+ Flow::Err
}
}
} else {
diff --git a/src/walk/walkers/core/key_value.rs b/src/walk/walkers/core/key_value.rs
index 36f2281..85a15a3 100644
--- a/src/walk/walkers/core/key_value.rs
+++ b/src/walk/walkers/core/key_value.rs
@@ -2,10 +2,7 @@ use crate::{
effect::{Effect, Future},
never::Never,
protocol::{
- visitor::{
- tag::{visit_tag, TagConst, TagError, TagKind},
- Status,
- },
+ visitor::{visit_tag, TagConst, TagError, TagKind, VisitResult},
Visitor,
},
walkers::core::noop::NoopWalker,
@@ -65,7 +62,7 @@ where
{
E::wrap(async move {
match visit_tag::<T, E, _>(self.tag, visitor, NoopWalker::new()).await {
- Ok(Status::Skipped(_)) => {
+ Ok(VisitResult::Skipped(_)) => {
match visit_tag::<TagConst<{ TAG_KEY_VALUE.to_int() }>, E, _>(
TagConst,
visitor,
@@ -73,13 +70,13 @@ where
)
.await
{
- Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(_flow)) => return Ok(()),
+ Ok(VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(_flow)) => return Ok(()),
Err(_) => todo!(),
}
}
- Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(_flow)) => todo!(),
+ Ok(VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(_flow)) => todo!(),
Err(_) => todo!(),
}
@@ -90,8 +87,8 @@ where
)
.await
{
- Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(_flow)) => return Ok(()),
+ Ok(VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(_flow)) => return Ok(()),
Err(_) => todo!(),
}
@@ -102,15 +99,15 @@ where
)
.await
{
- Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Skipped(value_walker)) => {
+ Ok(VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Skipped(value_walker)) => {
// Fallback to just walking the value.
match value_walker.walk(visitor).await {
Ok(_) => {}
Err(_err) => todo!(),
}
}
- Ok(Status::Flow(_flow)) => todo!(),
+ Ok(VisitResult::Control(_flow)) => todo!(),
Err(_) => todo!(),
}
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs
index 406e703..c6a2c8f 100644
--- a/src/walk/walkers/core/struct.rs
+++ b/src/walk/walkers/core/struct.rs
@@ -1,19 +1,22 @@
use core::any::TypeId;
use crate::{
- any::static_wrapper::{BorrowedStatic, DynBorrowedStatic}, any_trait, effect::{Effect, Future}, hkt::Marker, never::Never, protocol::{
+ any::BorrowedStatic,
+ any_trait,
+ effect::{Effect, Future},
+ hkt::Marker,
+ never::Never,
+ protocol::{
visitor::{
- recoverable::{visit_recoverable, DynRecoverable, RecoverableScope},
- request_hint::visit_request_hint,
- sequence::{visit_sequence, DynSequence, SequenceKnown, SequenceScope},
- tag::{visit_tag, DynTag, TagConst, TagDyn, TagError, TagHint, TagKnown},
- value::{visit_value, DynValue, ValueKnown},
- Status,
+ visit_recoverable, visit_request_hint, visit_sequence, visit_tag, visit_value,
+ DynRecoverable, DynSequence, DynTag, DynValue, RecoverableScope, SequenceKnown,
+ SequenceScope, TagConst, TagDyn, TagError, TagHint, TagKnown, ValueKnown, VisitResult,
},
walker::hint::{DynHint, HintMeta},
walker::hint::{Hint, Known},
Visitor,
- }, Flow, WalkerTypes, TAG_FIELD_NAMES, TAG_MAP, TAG_STRUCT, TAG_TYPE_ID, TAG_TYPE_NAME
+ },
+ Flow, Status, WalkerTypes, TAG_FIELD_NAMES, TAG_MAP, TAG_STRUCT, TAG_TYPE_ID, TAG_TYPE_NAME,
};
use super::{noop::NoopWalker, tag::StaticSliceWalker, value::ValueWalker};
@@ -135,7 +138,7 @@ any_trait! {
impl['ctx, T, I, M, E] StructWalker<'ctx, T, I, M, E> = [
DynHint<'ctx, DynRecoverable<'ctx, E>, E>,
DynHint<'ctx, DynSequence<'ctx, E>, E>,
- DynHint<'ctx, DynValue<'ctx, DynBorrowedStatic<'ctx, T>, E>, E>,
+ DynHint<'ctx, DynValue<'ctx, BorrowedStatic<'ctx, T>, E>, E>,
DynHint<'ctx, DynTag<'ctx, TagDyn, E>, E>,
DynHint<'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E>, E>,
DynHint<'ctx, DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E>, E>,
@@ -162,8 +165,8 @@ where
E::map(
visit_recoverable::<E>(visitor, self),
|status| match status {
- Status::Skipped(_) => Flow::Continue,
- Status::Flow(flow) => flow,
+ VisitResult::Skipped(_) => Flow::Continue,
+ VisitResult::Control(flow) => flow,
},
)
}
@@ -197,10 +200,10 @@ where
|status| match status {
Err(err) => {
self.error = Some(StructWalkErrorKind::FieldTag(err));
- Flow::Break
+ Flow::Err
}
- Ok(Status::Skipped(_)) => Flow::Continue,
- Ok(Status::Flow(flow)) => flow,
+ Ok(VisitResult::Skipped(_)) => Flow::Continue,
+ Ok(VisitResult::Control(flow)) => flow,
},
)
}
@@ -210,7 +213,8 @@ where
_hint: &'a <DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E> as HintMeta<
'ctx,
>>::Hint,
- ) -> Future<'a,
+ ) -> Future<
+ 'a,
Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, ()>,
E,
> {
@@ -241,10 +245,10 @@ where
|status| match status {
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- Flow::Break
+ Flow::Err
}
- Ok(Status::Skipped(_)) => Flow::Continue,
- Ok(Status::Flow(flow)) => flow,
+ Ok(VisitResult::Skipped(_)) => Flow::Continue,
+ Ok(VisitResult::Control(flow)) => flow,
},
)
}
@@ -280,10 +284,10 @@ where
|status| match status {
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- Flow::Break
+ Flow::Err
}
- Ok(Status::Skipped(_)) => Flow::Continue,
- Ok(Status::Flow(flow)) => flow,
+ Ok(VisitResult::Skipped(_)) => Flow::Continue,
+ Ok(VisitResult::Control(flow)) => flow,
},
)
}
@@ -291,11 +295,8 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<
- 'a,
- Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E>>, ()>,
- E,
- > {
+ ) -> Future<'a, Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E>>, ()>, E>
+ {
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
@@ -323,10 +324,10 @@ where
|status| match status {
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- Flow::Break
+ Flow::Err
}
- Ok(Status::Skipped(_)) => Flow::Continue,
- Ok(Status::Flow(flow)) => flow,
+ Ok(VisitResult::Skipped(_)) => Flow::Continue,
+ Ok(VisitResult::Control(flow)) => flow,
},
)
}
@@ -366,10 +367,10 @@ where
|status| match status {
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- Flow::Break
+ Flow::Err
}
- Ok(Status::Skipped(_)) => Flow::Continue,
- Ok(Status::Flow(flow)) => flow,
+ Ok(VisitResult::Skipped(_)) => Flow::Continue,
+ Ok(VisitResult::Control(flow)) => flow,
},
)
}
@@ -448,7 +449,7 @@ where
}
}
-impl<'ctx, T, I, M, E> Hint<'ctx, DynValue<'ctx, DynBorrowedStatic<'ctx, T>, E>, E>
+impl<'ctx, T, I, M, E> Hint<'ctx, DynValue<'ctx, BorrowedStatic<'ctx, T>, E>, E>
for StructWalker<'ctx, T, I, M, E>
where
E: Effect,
@@ -459,8 +460,8 @@ where
E::map(
visit_value::<_, E>(visitor, BorrowedStatic(self.value)),
|status| match status {
- Status::Skipped(_) => Flow::Continue,
- Status::Flow(flow) => flow,
+ VisitResult::Skipped(_) => Flow::Continue,
+ VisitResult::Control(flow) => flow,
},
)
}
@@ -482,8 +483,8 @@ where
_hint: <DynSequence<'ctx, E> as HintMeta<'ctx>>::Hint,
) -> Future<'a, Flow, E> {
E::map(visit_sequence::<E>(visitor, self), |status| match status {
- Status::Skipped(_) => Flow::Continue,
- Status::Flow(flow) => flow,
+ VisitResult::Skipped(_) => Flow::Continue,
+ VisitResult::Control(flow) => flow,
})
}
@@ -525,7 +526,7 @@ where
Err(err) => {
// Record the error and signal a break.
self.error = Some(StructWalkErrorKind::Field(err));
- Flow::Break
+ Flow::Err
}
},
)
@@ -538,7 +539,7 @@ where
I: StructTypeInfo<'ctx, M, T = T>,
T: Sync + 'static,
{
- fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E> {
+ fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Status, E> {
// Reset the errors to default state.
self.error = None;
@@ -548,14 +549,16 @@ where
E::wrap(async move {
// We should check if the visitor wants something specific.
match visit_request_hint::<E>(visitor, self).await {
- Flow::Continue => {}
- flow => return flow,
+ VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue) => {}
+ VisitResult::Control(Flow::Done) => return Ok(()),
+ VisitResult::Control(Flow::Err) => return Err(()),
}
// Attempt to visit the value directly.
match visit_value::<_, E>(visitor, BorrowedStatic(self.value)).await {
- Status::Skipped(_) | Status::Flow(Flow::Continue) => {}
- Status::Flow(flow) => return flow,
+ VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue) => {}
+ VisitResult::Control(Flow::Done) => return Ok(()),
+ VisitResult::Control(Flow::Err) => return Err(()),
}
// Follow the standard set of protocols for a struct.
@@ -574,10 +577,11 @@ where
{
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- return Flow::Break;
+ return Err(());
}
- Ok(Status::Skipped(_)) | Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => return flow,
+ Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
+ Ok(VisitResult::Control(Flow::Err)) => return Err(()),
}
match visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(
@@ -587,7 +591,7 @@ where
)
.await
{
- Ok(Status::Skipped(_)) => {
+ Ok(VisitResult::Skipped(_)) => {
match visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(
TagConst,
visitor,
@@ -597,18 +601,20 @@ where
{
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- return Flow::Break;
+ return Err(());
}
- Ok(Status::Skipped(_)) | Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => return flow,
+ Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
+ Ok(VisitResult::Control(Flow::Err)) => return Err(()),
}
}
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- return Flow::Break;
+ return Err(());
}
- Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => return flow,
+ Ok(VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
+ Ok(VisitResult::Control(Flow::Err)) => return Err(()),
}
match visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(
@@ -620,10 +626,11 @@ where
{
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
- return Flow::Break;
+ return Err(());
}
- Ok(Status::Skipped(_)) | Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => return flow,
+ Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
+ Ok(VisitResult::Control(Flow::Err)) => return Err(()),
}
match visit_tag::<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E, _>(
@@ -635,18 +642,20 @@ where
{
Err(err) => {
self.error = Some(StructWalkErrorKind::FieldTag(err));
- return Flow::Break;
+ return Err(());
}
- Ok(Status::Skipped(_)) | Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => return flow,
+ Ok(VisitResult::Skipped(_)) | Ok(VisitResult::Control(Flow::Continue)) => {}
+ Ok(VisitResult::Control(Flow::Done)) => return Ok(()),
+ Ok(VisitResult::Control(Flow::Err)) => return Err(()),
}
match visit_sequence::<E>(visitor, self).await {
- Status::Flow(Flow::Continue) | Status::Skipped(_) => {}
- Status::Flow(flow) => return flow,
+ VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => {}
+ VisitResult::Control(Flow::Done) => return Ok(()),
+ VisitResult::Control(Flow::Err) => return Err(()),
}
- Flow::Continue
+ Ok(())
})
}
}
diff --git a/src/walk/walkers/core/tag.rs b/src/walk/walkers/core/tag.rs
index 0deab96..bc6ba5a 100644
--- a/src/walk/walkers/core/tag.rs
+++ b/src/walk/walkers/core/tag.rs
@@ -1,21 +1,17 @@
use core::marker::PhantomData;
use crate::{
- any::static_wrapper::OwnedStatic,
+ any::OwnedStatic,
any_trait,
effect::{Effect, Future},
never::Never,
protocol::{
visitor::{
- request_hint::visit_request_hint,
- sequence::{DynSequence, SequenceScope},
- tag::TagError,
- value::visit_value,
- Status,
+ visit_request_hint, visit_value, DynSequence, SequenceScope, TagError, VisitResult,
},
Visitor,
},
- Flow, WalkerTypes
+ Flow, WalkerTypes,
};
pub struct StaticSliceWalker<T: 'static, W> {
@@ -56,13 +52,13 @@ where
{
E::wrap(async move {
match visit_request_hint::<E>(visitor, &mut self).await {
- Flow::Continue => {}
+ VisitResult::Skipped(_) | VisitResult::Control(Flow::Continue) => {}
_ => return Ok(()),
}
match visit_value::<_, E>(visitor, OwnedStatic(self.names)).await {
- Status::Skipped(_) => {}
- Status::Flow(Flow::Continue) => {}
+ VisitResult::Skipped(_) => {}
+ VisitResult::Control(Flow::Continue) => {}
_ => return Ok(()),
}
diff --git a/src/walk/walkers/core/value.rs b/src/walk/walkers/core/value.rs
index d5b35b9..2654a6c 100644
--- a/src/walk/walkers/core/value.rs
+++ b/src/walk/walkers/core/value.rs
@@ -1,8 +1,8 @@
use crate::{
- any::static_wrapper::{BorrowedStatic, OwnedStatic},
+ any::{BorrowedStatic, OwnedStatic},
effect::{Effect, Future},
never::Never,
- protocol::{visitor::value::visit_value, Visitor},
+ protocol::{visitor::visit_value, Visitor},
WalkerTypes,
};
@@ -72,9 +72,7 @@ impl<'ctx, T: ?Sized> WalkerTypes for BorrowWalker<'ctx, T> {
type Output = ();
}
-impl<'ctx, T: ?Sized + Sync + 'static, E: Effect> crate::Walker<'ctx, E>
- for BorrowWalker<'ctx, T>
-{
+impl<'ctx, T: ?Sized + Sync + 'static, E: Effect> crate::Walker<'ctx, E> for BorrowWalker<'ctx, T> {
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx>,
diff --git a/tests/common/builder.rs b/tests/common/builder.rs
index d2b182f..160846a 100644
--- a/tests/common/builder.rs
+++ b/tests/common/builder.rs
@@ -1,5 +1,10 @@
use mockall::mock;
-use treaty::{any::{indirect, AnyTrait, AnyTraitObject, TypeNameId}, effect::{Effect, Future}, protocol::Visitor, Builder, BuilderTypes};
+use treaty::{
+ any::{indirect, AnyTrait, AnyTraitObject, TypeNameId},
+ effect::{Effect, Future},
+ protocol::Visitor,
+ Builder, BuilderTypes,
+};
use crate::common::{ContextLock, StaticTypeMap};
diff --git a/tests/common/protocol.rs b/tests/common/protocol.rs
index e33df66..8320dc3 100644
--- a/tests/common/protocol.rs
+++ b/tests/common/protocol.rs
@@ -1,2 +1,2 @@
-pub mod visitor;
pub mod tag;
+pub mod visitor;
diff --git a/tests/common/protocol/tag.rs b/tests/common/protocol/tag.rs
index 23916d1..4a31f90 100644
--- a/tests/common/protocol/tag.rs
+++ b/tests/common/protocol/tag.rs
@@ -1,9 +1,14 @@
use mockall::mock;
-use treaty::{any::any_trait, effect::{Effect, Future}, protocol::visitor::tag::{DynTag, Tag, TagKind}, DynWalker};
+use treaty::{
+ any::any_trait,
+ effect::{Effect, Future},
+ protocol::visitor::{DynTag, Tag, TagKind, VisitResult},
+ DynWalker,
+};
mock! {
pub TagVisitor<K: TagKind, E> {
- pub fn visit<'a, 'ctx>(&'a mut self, kind: K, walker: DynWalker<'a, 'ctx, E>) -> K::Flow;
+ pub fn visit<'a, 'ctx>(&'a mut self, kind: K, walker: DynWalker<'a, 'ctx, E>) -> VisitResult<()>;
}
}
@@ -20,7 +25,10 @@ impl<'ctx, K: TagKind, E: Effect> Tag<'ctx, K, E> for MockTagVisitor<K, E> {
&'a mut self,
kind: K,
walker: DynWalker<'a, 'ctx, E>,
- ) -> Future<'a, <K as TagKind>::Flow, E> {
- E::ready(self.visit(kind, walker))
+ ) -> Future<'a, VisitResult<DynWalker<'a, 'ctx, E>>, E> {
+ E::ready(match self.visit(kind, walker) {
+ VisitResult::Skipped(_) => VisitResult::Skipped(walker),
+ VisitResult::Control(flow) => VisitResult::Control(flow),
+ })
}
}
diff --git a/tests/common/protocol/visitor.rs b/tests/common/protocol/visitor.rs
index a71e9ec..652f0b2 100644
--- a/tests/common/protocol/visitor.rs
+++ b/tests/common/protocol/visitor.rs
@@ -1,12 +1,17 @@
use mockall::mock;
-use treaty::{any::{any_trait, TypeName, WithContextLt}, effect::{Effect, Future}, protocol::visitor::value::{DynValue, Value}, Flow};
+use treaty::{
+ any::{any_trait, TypeName, WithContextLt},
+ effect::{Effect, Future},
+ protocol::visitor::{DynValue, Value, VisitResult},
+ Flow,
+};
mock! {
pub ValueVisitor<T: for<'ctx> WithContextLt::MemberType<'ctx>, E>
where
for<'a, 'ctx> WithContextLt::T<'a, 'ctx, T>: Sized
{
- pub fn visit<'a, 'ctx>(&'a mut self, value: WithContextLt::T<'a, 'ctx, T>) -> Flow;
+ pub fn visit<'a, 'ctx>(&'a mut self, value: WithContextLt::T<'a, 'ctx, T>) -> VisitResult<()>;
}
}
@@ -14,18 +19,27 @@ any_trait! {
impl['ctx, T, E] MockValueVisitor<T, E> = [
DynValue<'ctx, T, E>
] where
- T: for<'lt> TypeName::LowerType<'lt> + 'ctx,
- for<'a, 'lt> WithContextLt::T<'a, 'lt, T>: Sized,
+ T: for<'lt> TypeName::LowerType<'lt> + Send + 'ctx,
+ for<'a, 'lt> WithContextLt::T<'a, 'lt, T>: Clone + Sized,
E: Effect,
}
impl<'ctx, T: for<'lt> WithContextLt::MemberType<'lt>, E: Effect> Value<'ctx, T, E>
for MockValueVisitor<T, E>
where
- for<'a, 'lt> WithContextLt::T<'a, 'lt, T>: Sized,
+ for<'a, 'lt> WithContextLt::T<'a, 'lt, T>: Sized + Clone,
{
- fn visit<'a>(&'a mut self, value: WithContextLt::T<'a, 'ctx, T>) -> Future<'a, Flow, E>
- where 'ctx: 'a {
- E::ready(self.visit(value))
+ fn visit<'a>(
+ &'a mut self,
+ value: WithContextLt::T<'a, 'ctx, T>,
+ ) -> Future<'a, VisitResult<WithContextLt::T<'a, 'ctx, T>>, E>
+ where
+ WithContextLt::T<'a, 'ctx, T>: Send,
+ 'ctx: 'a,
+ {
+ E::ready(match self.visit(value.clone()) {
+ VisitResult::Skipped(_) => VisitResult::Skipped(value),
+ VisitResult::Control(flow) => VisitResult::Control(flow),
+ })
}
}
diff --git a/tests/protocol_visitor_value.rs b/tests/protocol_visitor_value.rs
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/protocol_visitor_value.rs
@@ -0,0 +1 @@
+
diff --git a/tests/walkers/core/struct.rs b/tests/walkers/core/struct.rs
index 9ea8c31..5ac0926 100644
--- a/tests/walkers/core/struct.rs
+++ b/tests/walkers/core/struct.rs
@@ -1,7 +1,22 @@
use mockall::{predicate::eq, Sequence};
-use treaty::{any::{static_wrapper::{DynOwnedStatic, OwnedStatic}, TypeNameId}, effect::{BlockOn, Blocking, Effect, Future, Spin}, protocol::{visitor::{tag::{DynTag, TagConst}, value::DynValue}, Visitor}, walkers::core::{r#struct::{StructTypeInfo, StructWalker}, value::ValueWalker}, Builder, DefaultMode, Flow, Walker, TAG_STRUCT, TAG_TYPE_NAME};
-
-use crate::common::{builder::MockBuilder, protocol::{tag::MockTagVisitor, visitor::MockValueVisitor}};
+use treaty::{
+ any::{OwnedStatic, TypeNameId},
+ effect::{BlockOn, Blocking, Effect, Future, Spin},
+ protocol::{
+ visitor::{DynTag, DynValue, TagConst},
+ Visitor,
+ },
+ walkers::core::{
+ r#struct::{StructTypeInfo, StructWalker},
+ value::ValueWalker,
+ },
+ Builder, DefaultMode, Flow, Walker, TAG_STRUCT, TAG_TYPE_NAME,
+};
+
+use crate::common::{
+ builder::MockBuilder,
+ protocol::{tag::MockTagVisitor, visitor::MockValueVisitor},
+};
struct Demo {
a: bool,
@@ -69,7 +84,7 @@ fn demo2() {
Flow::Done
);
- Flow::Continue
+ Flow::Continue.into()
});
mock
@@ -83,8 +98,7 @@ fn demo2() {
>()))
.in_sequence(&mut seq)
.return_var(Some(Box::new({
- let mut mock =
- MockTagVisitor::<TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>::new();
+ let mut mock = MockTagVisitor::<TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>::new();
mock.expect_visit().return_once(|_, walker| {
let mut builder = MockBuilder::<(), (), ()>::new();
@@ -93,11 +107,11 @@ fn demo2() {
.expect_traits_mut()
.once()
.with(eq(TypeNameId::of::<
- DynValue<'static, DynOwnedStatic<&'static str>, Blocking>,
+ DynValue<'static, OwnedStatic<&'static str>, Blocking>,
>()))
.return_var(Some(Box::new({
let mut mock =
- MockValueVisitor::<DynOwnedStatic<&'static str>, Blocking>::new();
+ MockValueVisitor::<OwnedStatic<&'static str>, Blocking>::new();
mock.expect_visit()
.once()
@@ -112,7 +126,7 @@ fn demo2() {
Flow::Done
);
- Flow::Continue
+ Flow::Continue.into()
});
mock