-rw-r--r--Cargo.toml4
-rw-r--r--src/any.rs36
-rw-r--r--src/any/indirect.rs8
-rw-r--r--src/any/static_wrapper.rs44
-rw-r--r--src/any/type_name_id.rs2
-rw-r--r--src/build.rs8
-rw-r--r--src/build/builders/core/bool.rs19
-rw-r--r--src/build/builders/debug.rs64
-rw-r--r--src/effect.rs69
-rw-r--r--src/hkt.rs261
-rw-r--r--src/lib.rs103
-rw-r--r--src/mock.rs81
-rw-r--r--src/mock/protocol.rs2
-rw-r--r--src/protocol/visitor/recoverable.rs32
-rw-r--r--src/protocol/visitor/request_hint.rs12
-rw-r--r--src/protocol/visitor/sequence.rs29
-rw-r--r--src/protocol/visitor/tag.rs22
-rw-r--r--src/protocol/visitor/value.rs65
-rw-r--r--src/protocol/walker/hint.rs149
-rw-r--r--src/symbol.rs15
-rw-r--r--src/transform.rs5
-rw-r--r--src/walk.rs14
-rw-r--r--src/walk/walkers/core/bool.rs6
-rw-r--r--src/walk/walkers/core/key_value.rs15
-rw-r--r--src/walk/walkers/core/noop.rs6
-rw-r--r--src/walk/walkers/core/struct.rs242
-rw-r--r--src/walk/walkers/core/tag.rs24
-rw-r--r--src/walk/walkers/core/value.rs8
-rw-r--r--tests/async.rs148
-rw-r--r--tests/common/builder.rs (renamed from src/mock/builder.rs)20
-rw-r--r--tests/common/mod.rs83
-rw-r--r--tests/common/protocol.rs2
-rw-r--r--tests/common/protocol/tag.rs (renamed from src/mock/protocol/tag.rs)15
-rw-r--r--tests/common/protocol/visitor.rs (renamed from src/mock/protocol/value.rs)17
-rw-r--r--tests/demo.rs192
-rw-r--r--tests/demo2.rs14
-rw-r--r--tests/hook.rs138
-rw-r--r--tests/walk.rs3
-rw-r--r--tests/walkers/core.rs1
-rw-r--r--tests/walkers/core/struct.rs132
-rw-r--r--tests/walkers/mod.rs1
41 files changed, 760 insertions, 1351 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 1f09357..8fc6d84 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,14 +11,12 @@ include = ["LICENSE-APACHE", "LICENSE-MIT", "README.md", "empty.rs"]
[dependencies]
serde = { version = "1.0", default-features = false, optional = true }
-mockall = { version = "0.12.1", optional = true }
[features]
-default = ["std", "serde", "mock"]
+default = ["std", "serde", "better_errors"]
std = ["alloc", "serde?/std"]
alloc = ["serde?/alloc"]
serde = ["dep:serde"]
-mock = ["std", "dep:mockall"]
better_errors = []
[dev-dependencies]
diff --git a/src/any.rs b/src/any.rs
index da0f369..5df514c 100644
--- a/src/any.rs
+++ b/src/any.rs
@@ -6,7 +6,7 @@ pub mod indirect;
pub mod static_wrapper;
mod type_name_id;
-use crate::{bijective_higher_ranked_trait, bijective_higher_ranked_type};
+use crate::{bijective_higher_ranked_trait, bijective_higher_ranked_type, hkt::Invariant};
use core::marker::PhantomData;
pub use type_name_id::*;
@@ -118,17 +118,18 @@ bijective_higher_ranked_type! {
/// by `id` if [`AnyTrait`] had every trait as a super bound.
///
/// ```
-/// use treaty::any::{AnyTrait, any_trait, nameable};
+/// use treaty::any::{AnyTrait, any_trait, WithContextLt, TypeName};
+/// use treaty::hkt::bijective_higher_ranked_type;
///
/// // Create a test value.
/// let my_num = MyNum(42);
///
/// // Cast to be a AnyTrait trait object.
/// // Now we don't know the type.
-/// let anything: &dyn AnyTrait<'_> = &my_num;
+/// let anything: &(dyn AnyTrait<'_> + Send) = &my_num;
///
/// // We can still upcast to an impl of ToNum.
-/// let to_num_object: &dyn ToNum = anything.upcast().unwrap();
+/// let to_num_object: &dyn ToNum = anything.upcast::<DynToNum>().unwrap();
///
/// assert_eq!(to_num_object.num(), 42);
///
@@ -139,10 +140,15 @@ bijective_higher_ranked_type! {
/// fn num(&self) -> i32;
/// }
///
+/// bijective_higher_ranked_type! {
+/// for['ctx] type DynToNum[][]: WithContextLt['ctx][]
+/// for<'a> (dyn ToNum + 'a)
+/// }
+///
/// // Make the trait object nameable.
-/// nameable! {
-/// struct Name['a, 'ctx];
-/// impl for dyn ToNum + 'a where { }
+/// bijective_higher_ranked_type! {
+/// type [][]: TypeName[][]
+/// for<'ctx> (DynToNum)
/// }
///
/// // An example struct.
@@ -159,7 +165,7 @@ bijective_higher_ranked_type! {
/// // Here the only trait that can be looked up is ToNum as its the only
/// // one in the list.
/// any_trait! {
-/// impl['a, 'ctx] MyNum = [dyn ToNum + 'a];
+/// impl['ctx] MyNum = [DynToNum]
/// }
/// ```
pub trait AnyTrait<'ctx> {
@@ -346,15 +352,8 @@ pub struct AnyTraitObject<'a, 'ctx: 'a, I: Indirect<'a>> {
/// This is some form of &T where T may be sized or not.
indirect: RawIndirect<'a, I>,
- /// Extra type information for the type system.
- _marker: PhantomData<(
- // Invariant over 'a and 'ctx, the TypeNameId doesn't track lifetimes so we have to do it
- // here.
- // https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns
- fn(&'ctx ()) -> &'ctx (),
- // Not Send or Sync.
- *const (),
- )>,
+ _lifetime: Invariant<'ctx>,
+ _not_send_sync: PhantomData<*const ()>,
}
impl<'a, 'ctx, I: Indirect<'a>> AnyTraitObject<'a, 'ctx, I> {
@@ -368,7 +367,8 @@ impl<'a, 'ctx, I: Indirect<'a>> AnyTraitObject<'a, 'ctx, I> {
Self {
info: TypeNameId::of_lower::<T>,
indirect: RawIndirect::new(indirect),
- _marker: PhantomData,
+ _lifetime: Default::default(),
+ _not_send_sync: PhantomData,
}
}
diff --git a/src/any/indirect.rs b/src/any/indirect.rs
index eef24f0..ae70ef3 100644
--- a/src/any/indirect.rs
+++ b/src/any/indirect.rs
@@ -16,7 +16,7 @@ pub trait HigherKinded<'a> {
pub trait Indirect<'a>: HigherKinded<'a> + sealed::Sealed<'a> {}
pub(super) mod sealed {
- use core::marker::PhantomData;
+ use crate::hkt::{Invariant, Marker};
use super::*;
@@ -41,14 +41,16 @@ pub(super) mod sealed {
#[repr(transparent)]
pub struct RawIndirect<'a, I> {
indirect: MaybeUninit<[u8; INDIRECT_SIZE]>,
- _marker: PhantomData<fn(&'a ()) -> (&'a (), I)>,
+ _lifetime: Invariant<'a>,
+ _generic: Marker<I>
}
impl<'a, I: Indirect<'a>> RawIndirect<'a, I> {
pub fn new<T: ?Sized>(indirect: I::ForT<T>) -> Self {
Self {
indirect: I::into_raw(indirect),
- _marker: PhantomData,
+ _lifetime: Default::default(),
+ _generic: Default::default()
}
}
diff --git a/src/any/static_wrapper.rs b/src/any/static_wrapper.rs
index 4b238b9..c99b037 100644
--- a/src/any/static_wrapper.rs
+++ b/src/any/static_wrapper.rs
@@ -7,19 +7,14 @@ use super::*;
#[repr(transparent)]
pub struct OwnedStatic<T: ?Sized>(pub T);
-/// Higher ranked type for [`OwnedStatic`].
-pub struct DynOwnedStatic<T: ?Sized>(PhantomData<fn() -> *const T>);
-
-impl<'a, 'ctx, T: ?Sized + 'ctx> WithContextLt::LowerForLt<'a, 'ctx, &'a (&'ctx (),)>
- for DynOwnedStatic<T>
-{
- type T = OwnedStatic<T>;
-}
-
-impl<'a, 'ctx, T: ?Sized + 'ctx> WithContextLt::RaiseForLt<'a, 'ctx, &'a (&'ctx (),)>
- for OwnedStatic<T>
-{
- type HigherRanked = DynOwnedStatic<T>;
+bijective_higher_ranked_type! {
+ /// Higher ranked type for [`OwnedStatic`].
+ pub for['ctx] type DynOwnedStatic[][T]: WithContextLt['ctx][]
+ for<'a>
+ (OwnedStatic<T>)
+ where {
+ T: ?Sized + 'ctx,
+ }
}
bijective_higher_ranked_type! {
@@ -128,22 +123,15 @@ bijective_higher_ranked_type! {
#[repr(transparent)]
pub struct BoxedStatic<T: ?Sized>(pub Box<T>);
-/// Higher ranked type for [`BoxedStatic`].
-#[cfg(feature = "alloc")]
-pub struct DynBoxedStatic<T: ?Sized>(PhantomData<fn() -> *const T>);
-
#[cfg(feature = "alloc")]
-impl<'a, 'ctx, T: ?Sized + 'ctx> WithContextLt::LowerForLt<'a, 'ctx, &'a (&'ctx (),)>
- for DynBoxedStatic<T>
-{
- type T = BoxedStatic<T>;
-}
-
-#[cfg(feature = "alloc")]
-impl<'a, 'ctx, T: ?Sized + 'ctx> WithContextLt::RaiseForLt<'a, 'ctx, &'a (&'ctx (),)>
- for BoxedStatic<T>
-{
- type HigherRanked = DynBoxedStatic<T>;
+bijective_higher_ranked_type! {
+ /// Higher ranked type for [`BoxedStatic`].
+ pub for['ctx] type DynBoxedStatic[][T]: WithContextLt['ctx][]
+ for<'a>
+ (BoxedStatic<T>)
+ where {
+ T: ?Sized + 'ctx,
+ }
}
#[cfg(feature = "alloc")]
diff --git a/src/any/type_name_id.rs b/src/any/type_name_id.rs
index 5198073..2ba7ffc 100644
--- a/src/any/type_name_id.rs
+++ b/src/any/type_name_id.rs
@@ -88,7 +88,7 @@ impl Eq for TypeNameId {}
impl PartialOrd for TypeNameId {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
- self.name_id.partial_cmp(&other.name_id)
+ Some(self.name_id.cmp(&other.name_id))
}
}
diff --git a/src/build.rs b/src/build.rs
index 24232a0..d77bb39 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -6,7 +6,7 @@ use crate::{
};
/// A buildable type.
-pub trait Build<'ctx, M, E: Effect<'ctx>>: BuilderTypes<Value = Self> + Send {
+pub trait Build<'ctx, M, E: Effect>: BuilderTypes<Value = Self> + Send {
/// The builder that can be used to build a value of `Self`.
type Builder: Builder<'ctx, E, Seed = Self::Seed, Error = Self::Error, Value = Self>;
}
@@ -34,8 +34,8 @@ pub trait BuilderTypes {
/// the builder with data from it's walk.
/// - Call [`Self::build()`] to finish building the value and get any errors
/// that happened during filling it with data.
-pub trait Builder<'ctx, E: Effect<'ctx>>: BuilderTypes + Sized + Send {
- fn from_seed<'a>(seed: Self::Seed) -> Future<'a, 'ctx, Self, E>
+pub trait Builder<'ctx, E: Effect>: BuilderTypes + Sized + Send {
+ fn from_seed<'a>(seed: Self::Seed) -> Future<'a, Self, E>
where
Self: 'a;
@@ -43,7 +43,7 @@ pub trait Builder<'ctx, E: Effect<'ctx>>: BuilderTypes + Sized + Send {
///
/// If an error happened with the builder during the walk
/// it will be reported here.
- fn build<'a>(self) -> Future<'a, 'ctx, Result<Self::Value, Self::Error>, E>
+ fn build<'a>(self) -> Future<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a;
diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs
index 208e88b..fd41ed6 100644
--- a/src/build/builders/core/bool.rs
+++ b/src/build/builders/core/bool.rs
@@ -1,4 +1,4 @@
-use core::{marker::PhantomData, ops::ControlFlow};
+use core::marker::PhantomData;
use crate::{
any::static_wrapper::{DynOwnedStatic, OwnedStatic},
@@ -11,7 +11,7 @@ use crate::{
Flow,
};
-impl<'ctx, M, E: Effect<'ctx>> crate::Build<'ctx, M, E> for bool {
+impl<'ctx, M, E: Effect> crate::Build<'ctx, M, E> for bool {
type Builder = Builder<E>;
}
@@ -38,16 +38,16 @@ impl<E> crate::BuilderTypes for Builder<E> {
type Seed = ();
}
-impl<'ctx, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<E> {
+impl<'ctx, E: Effect> crate::Builder<'ctx, E> for Builder<E> {
#[inline]
- fn build<'a>(self) -> Future<'a, 'ctx, Result<Self::Value, Self::Error>, E>
+ fn build<'a>(self) -> Future<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a,
{
E::wrap(core::future::ready(self.0.ok_or(Error::Incomplete)))
}
- fn from_seed<'a>(_seed: Self::Seed) -> Future<'a, 'ctx, Self, E>
+ fn from_seed<'a>(_seed: Self::Seed) -> Future<'a, Self, E>
where
Self: 'a,
{
@@ -62,12 +62,15 @@ impl<'ctx, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<E> {
any_trait! {
impl['ctx, E] Builder<E> = [
DynValue<'ctx, DynOwnedStatic<bool>, E>,
- ] where E: Effect<'ctx>
+ ] where E: Effect
}
-impl<'ctx, E: Effect<'ctx>> Value<'ctx, DynOwnedStatic<bool>, E> for Builder<E> {
+impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<bool>, E> for Builder<E> {
#[inline]
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, 'ctx, Flow, E> {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, Flow, E>
+ where
+ 'ctx: 'a
+ {
self.0 = Some(value);
E::ready(Flow::Continue)
}
diff --git a/src/build/builders/debug.rs b/src/build/builders/debug.rs
index 54efc96..68d9de6 100644
--- a/src/build/builders/debug.rs
+++ b/src/build/builders/debug.rs
@@ -1,13 +1,9 @@
-use core::{any::TypeId, marker::PhantomData, ops::ControlFlow};
+use core::{any::TypeId, marker::PhantomData};
use crate::{
- any::{
- static_wrapper::{DynOwnedStatic, OwnedStatic},
- TypeNameId,
- },
+ any::static_wrapper::{DynOwnedStatic, OwnedStatic},
any_trait,
effect::{Effect, Future},
- never::Never,
protocol::{
self,
visitor::{
@@ -38,10 +34,16 @@ any_trait! {
let id;
println!("Unknown trait: {:?}", id);
None
- } where E: Effect<'ctx>
+ } where E: Effect
+}
+
+impl<E: Effect> Default for Visitor<E> {
+ fn default() -> Self {
+ Self::new()
+ }
}
-impl<'ctx, E: Effect<'ctx>> Visitor<E> {
+impl<E: Effect> Visitor<E> {
pub fn new() -> Self {
Self(0, PhantomData)
}
@@ -56,11 +58,11 @@ impl<'ctx, E: Effect<'ctx>> Visitor<E> {
}
}
-impl<'ctx, E: Effect<'ctx>> RequestHint<'ctx, E> for 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, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
// self.tab();
// println!("Visit request hint (no hint given)");
// println!("Visit request hint (hint for recoverable)");
@@ -68,12 +70,12 @@ impl<'ctx, E: Effect<'ctx>> RequestHint<'ctx, E> for Visitor<E> {
}
}
-impl<'ctx, E: Effect<'ctx>> Tag<'ctx, TagDyn, E> for Visitor<E> {
+impl<'ctx, E: Effect> Tag<'ctx, TagDyn, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
kind: TagDyn,
walker: DynWalker<'a, 'ctx, E>,
- ) -> Future<'a, 'ctx, Status, E> {
+ ) -> Future<'a, Status, E> {
E::wrap(async move {
match kind.0 {
crate::TAG_TYPE_NAME => {
@@ -81,7 +83,7 @@ impl<'ctx, E: Effect<'ctx>> Tag<'ctx, TagDyn, E> for Visitor<E> {
println!("type name:");
self.0 += 1;
- walker.walk(self).await;
+ let _ = walker.walk(self).await;
self.0 -= 1;
Status::r#continue()
@@ -91,7 +93,7 @@ impl<'ctx, E: Effect<'ctx>> Tag<'ctx, TagDyn, E> for Visitor<E> {
println!("key:");
self.0 += 1;
- walker.walk(self).await;
+ let _ = walker.walk(self).await;
self.0 -= 1;
Status::r#continue()
@@ -101,7 +103,7 @@ impl<'ctx, E: Effect<'ctx>> Tag<'ctx, TagDyn, E> for Visitor<E> {
println!("value:");
self.0 += 1;
- walker.walk(self).await;
+ let _ = walker.walk(self).await;
self.0 -= 1;
Status::r#continue()
@@ -112,63 +114,71 @@ impl<'ctx, E: Effect<'ctx>> Tag<'ctx, TagDyn, E> for Visitor<E> {
}
}
-impl<'ctx, E: Effect<'ctx>> Value<'ctx, DynOwnedStatic<&'static str>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<&'static str>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<&'static str>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where
+ 'ctx: 'a
+ {
self.tab();
println!("{:?}", value);
E::ready(Flow::Continue)
}
}
-impl<'ctx, E: Effect<'ctx>> Value<'ctx, DynOwnedStatic<usize>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<usize>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<usize>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where
+ 'ctx: 'a {
self.tab();
println!("{}", value);
E::ready(Flow::Continue)
}
}
-impl<'ctx, E: Effect<'ctx>> Value<'ctx, DynOwnedStatic<bool>, E> for Visitor<E> {
- fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, 'ctx, Flow, E> {
+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{
self.tab();
println!("{}", value);
E::ready(Flow::Continue)
}
}
-impl<'ctx, E: Effect<'ctx>> Value<'ctx, DynOwnedStatic<&'static [&'static str]>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<&'static [&'static str]>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<&'static [&'static str]>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where 'ctx: 'a{
self.tab();
println!("{:?}", value);
E::ready(Flow::Continue)
}
}
-impl<'ctx, E: Effect<'ctx>> Value<'ctx, DynOwnedStatic<TypeId>, E> for Visitor<E> {
+impl<'ctx, E: Effect> Value<'ctx, DynOwnedStatic<TypeId>, E> for Visitor<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<TypeId>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where 'ctx: 'a{
self.tab();
println!("Visit type ID: {:?}", value);
E::ready(Flow::Continue)
}
}
-impl<'ctx, E: Effect<'ctx>> Sequence<'ctx, E> for Visitor<E> {
+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, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::wrap(async {
self.tab();
println!("sequence{:?}", scope.size_hint().await);
diff --git a/src/effect.rs b/src/effect.rs
index b52f94a..71e4aec 100644
--- a/src/effect.rs
+++ b/src/effect.rs
@@ -5,33 +5,30 @@ use core::{
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
-use crate::{higher_ranked_trait, higher_ranked_type};
+use crate::{bijective_higher_ranked_type, bijective_higher_ranked_trait};
-higher_ranked_trait! {
- pub type class SendFuture['ctx, Output]: [for<'lt> core::future::Future<Output = Output> + Send + 'lt]
+bijective_higher_ranked_trait! {
+ pub type class SendFuture[][Output]: [for<'lt> core::future::Future<Output = Output> + Sized + Send + 'lt]
where {
Output: Send,
}
- for where {
- Output: 'lt,
- }
}
/// Trait for effects.
-pub trait Effect<'ctx>: Send + 'static {
- type Future<T: Send>: SendFuture::Trait<'ctx, T>;
+pub trait Effect: Send + 'static {
+ type Future<T: Send>: SendFuture::MemberType<T>;
- fn wrap<'a, F>(future: F) -> SendFuture::T<'a, 'ctx, Self::Future<F::Output>, F::Output>
+ fn wrap<'a, F>(future: F) -> SendFuture::T<'a, Self::Future<F::Output>, F::Output>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send;
- fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, 'ctx, Self::Future<T>, T>;
+ fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, Self::Future<T>, T>;
fn map<'a, T, U, F>(
- future: SendFuture::T<'a, 'ctx, Self::Future<T>, T>,
+ future: SendFuture::T<'a, Self::Future<T>, T>,
func: F,
- ) -> SendFuture::T<'a, 'ctx, Self::Future<U>, U>
+ ) -> SendFuture::T<'a, Self::Future<U>, U>
where
T: Send,
U: Send,
@@ -41,7 +38,7 @@ pub trait Effect<'ctx>: Send + 'static {
#[inline]
fn wrap_boxed<'a, F>(
future: core::pin::Pin<Box<F>>,
- ) -> SendFuture::T<'a, 'ctx, Self::Future<F::Output>, F::Output>
+ ) -> SendFuture::T<'a, Self::Future<F::Output>, F::Output>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send,
@@ -50,7 +47,7 @@ pub trait Effect<'ctx>: Send + 'static {
}
}
-pub type Future<'a, 'ctx, T, E> = SendFuture::T<'a, 'ctx, <E as Effect<'ctx>>::Future<T>, T>;
+pub type Future<'a, T, E> = SendFuture::T<'a, <E as Effect>::Future<T>, T>;
pub struct Blocking<B = Spin> {
_marker: PhantomData<fn() -> B>,
@@ -88,7 +85,7 @@ impl BlockOn for Spin {
#[inline]
pub fn noop() -> Waker {
- const VTABLE: &'static RawWakerVTable = &RawWakerVTable::new(
+ const VTABLE: &RawWakerVTable = &RawWakerVTable::new(
// Cloning just returns a new no-op raw waker
|_| RAW,
// `wake` does nothing
@@ -98,21 +95,22 @@ pub fn noop() -> Waker {
// Dropping does nothing as we don't allocate anything
|_| {},
);
- const RAW: RawWaker = RawWaker::new(ptr::null(), &VTABLE);
+ const RAW: RawWaker = RawWaker::new(ptr::null(), VTABLE);
unsafe { Waker::from_raw(RAW) }
}
-higher_ranked_type! {
- pub type ReadyFuture['ctx, Output]: (SendFuture)[Output]
+bijective_higher_ranked_type! {
+ pub type ReadyFuture[][Output]: SendFuture[][Output]
+ for<'lt> (core::future::Ready<Output>)
where {
Output: Send,
- } = for<'lt> core::future::Ready<Output>
+ }
}
-impl<'ctx, B: BlockOn> Effect<'ctx> for Blocking<B> {
- type Future<T: Send> = ReadyFuture<'ctx, T>;
+impl<B: BlockOn> Effect for Blocking<B> {
+ type Future<T: Send> = ReadyFuture<T>;
- fn wrap<'a, F>(future: F) -> SendFuture::T<'a, 'ctx, Self::Future<F::Output>, F::Output>
+ fn wrap<'a, F>(future: F) -> SendFuture::T<'a, Self::Future<F::Output>, F::Output>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send,
@@ -120,14 +118,14 @@ impl<'ctx, B: BlockOn> Effect<'ctx> for Blocking<B> {
core::future::ready(B::block_on(future))
}
- fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, 'ctx, Self::Future<T>, T> {
+ fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, Self::Future<T>, T> {
core::future::ready(value)
}
fn map<'a, T, U, F>(
- future: SendFuture::T<'a, 'ctx, Self::Future<T>, T>,
+ future: SendFuture::T<'a, Self::Future<T>, T>,
func: F,
- ) -> SendFuture::T<'a, 'ctx, Self::Future<U>, U>
+ ) -> SendFuture::T<'a, Self::Future<U>, U>
where
T: Send,
U: Send,
@@ -160,21 +158,22 @@ mod sealed {
}
#[cfg(feature = "alloc")]
-higher_ranked_type! {
- pub type BoxFuture['ctx, Output]: (SendFuture)[Output]
+bijective_higher_ranked_type! {
+ pub type BoxFuture[][Output]: SendFuture[][Output]
+ for<'lt> (sealed::BoxedFuture<'lt, Output>)
where {
Output: Send,
- } = for<'lt> sealed::BoxedFuture<'lt, Output>
+ }
}
#[cfg(feature = "alloc")]
pub enum Async {}
#[cfg(feature = "alloc")]
-impl<'ctx> Effect<'ctx> for Async {
- type Future<T: Send> = BoxFuture<'ctx, T>;
+impl Effect for Async {
+ type Future<T: Send> = BoxFuture<T>;
- fn wrap<'a, F>(future: F) -> SendFuture::T<'a, 'ctx, Self::Future<F::Output>, F::Output>
+ fn wrap<'a, F>(future: F) -> SendFuture::T<'a, Self::Future<F::Output>, F::Output>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send,
@@ -182,14 +181,14 @@ impl<'ctx> Effect<'ctx> for Async {
sealed::BoxedFuture::Box(Box::pin(future))
}
- fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, 'ctx, Self::Future<T>, T> {
+ fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, Self::Future<T>, T> {
sealed::BoxedFuture::Ready(core::future::ready(value))
}
fn map<'a, T, U, F>(
- future: SendFuture::T<'a, 'ctx, Self::Future<T>, T>,
+ future: SendFuture::T<'a, Self::Future<T>, T>,
func: F,
- ) -> SendFuture::T<'a, 'ctx, Self::Future<U>, U>
+ ) -> SendFuture::T<'a, Self::Future<U>, U>
where
T: Send,
U: Send,
@@ -206,7 +205,7 @@ impl<'ctx> Effect<'ctx> for Async {
fn wrap_boxed<'a, F>(
future: core::pin::Pin<Box<F>>,
- ) -> SendFuture::T<'a, 'ctx, Self::Future<F::Output>, F::Output>
+ ) -> SendFuture::T<'a, Self::Future<F::Output>, F::Output>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send,
diff --git a/src/hkt.rs b/src/hkt.rs
index 83a051e..f51ebed 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -19,82 +19,31 @@
//! 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.
-/// Used to cause `'lt` to have extra bounds when using `for<'lt>` syntax.
-///
-/// Including this type where a `for<'lt>` is being generated will result in the following bounds
-/// being applied.
-/// * `'bound: 'lt` - `'lt` will **not** outlive `'bound`.
-/// * `T: 'lt` - `T` will outlive `'lt`.
-pub type Bound<'lt, 'bound, T = ()> = (&'lt &'bound (), &'lt T);
+#[derive(Debug, Default, Copy, Clone)]
+#[repr(transparent)]
+pub struct Invariant<'a>(PhantomData<fn(&'a ()) -> &'a ()>);
-/// Generate a higher-ranked trait.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! higher_ranked_trait {
- {
- $vis:vis type class $name:ident[$ctx:lifetime $(, $($generic:tt)*)?]: [for<$lt:lifetime> $($($provides:tt)+)?]
- $(where {
- $($bound:tt)*
- })?
- $(for where {
- $($for_bound:tt)*
- })?
- } => {
- $vis mod $name {
- #![allow(unused, non_snake_case)]
-
- use super::*;
-
- pub trait ForLt<$lt, $ctx: $lt, B $(, $($generic)*)?>
- where $($($bound)*)? $($($for_bound)*)?
-
- {
- type T: $lt $(+ $($provides)+)?;
- }
-
- pub trait Trait<$ctx $(, $($generic)*)?>: for<$lt> ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx $(, $($generic)*)?> $(, $($generic)*)?>
- where
- $($($bound)*)?
- {}
-
- impl<$ctx, ____ $(, $($generic)*)?> Trait<$ctx $(, $($generic)*)?> for ____
- where
- ____: for<$lt> ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx $(, $($generic)*)?> $(, $($generic)*)?>,
- $($($bound)*)?
- {}
+#[repr(transparent)]
+pub struct Marker<T>(PhantomData<fn() -> T>);
- pub type T<$lt, $ctx, H $(, $($generic)*)?> = <H as ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx $(, $($generic)*)?> $(, $($generic)*)?>>::T;
- }
- };
+impl<T> Copy for Marker<T> {}
+impl<T> Clone for Marker<T> {
+ fn clone(&self) -> Self {
+ *self
+ }
}
-use core::marker::PhantomData;
-
-#[doc(inline)]
-pub use higher_ranked_trait;
-
-/// Generate a higher-ranked type.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! higher_ranked_type {
- {
- $vis:vis type $name:ident[$ctx:lifetime $(, $($generic:tt)*)?]: ($($type_class:tt)*)$([$($type_class_generic:tt)*])?
- $(where {$($bound:tt)*})?
- = for<$lt:lifetime> $for_lt_type:ty
- $(where {$($higher_bound:tt)*})?
- } => {
- $vis struct $name<$ctx $(, $($generic)*)?>(core::marker::PhantomData<fn() -> (&$ctx (), $($($generic)*)?)>);
-
- impl<$lt, $ctx $(, $($generic)*)?> $($type_class)*::ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx $(, $($generic)*)?> $(, $($type_class_generic)*)?> for $name<$ctx $(, $($generic)*)?>
- where $($($bound)*)? $($($higher_bound)*)?
- {
- type T = $for_lt_type;
- }
+impl<T> core::fmt::Debug for Marker<T> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ f.debug_tuple("Marker").finish()
}
}
-#[doc(inline)]
-pub use higher_ranked_type;
+impl<T> Default for Marker<T> {
+ fn default() -> Self {
+ Self(PhantomData)
+ }
+}
#[doc(hidden)]
#[macro_export]
@@ -139,7 +88,7 @@ macro_rules! bijective_higher_ranked_trait {
type T: ?Sized + RaiseForLt<
$lt,
$($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic,)*
HigherRanked = Self
> $(+ $($provides)+)? + $lt;
@@ -163,7 +112,7 @@ macro_rules! bijective_higher_ranked_trait {
type HigherRanked: ?Sized + LowerForLt<
$lt,
$($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic,)*
T = Self
> $(+ $lifetimes)*;
@@ -181,7 +130,7 @@ macro_rules! bijective_higher_ranked_trait {
$($lifetimes,)*
// Use a implied bound to make sure the lifetime from the for syntax is
// correctly bounded.
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic),*
>
where
@@ -198,7 +147,7 @@ macro_rules! bijective_higher_ranked_trait {
__: for<$lt> LowerForLt<
$lt,
$($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic),*
>,
$($($bound)*)?
@@ -209,7 +158,7 @@ macro_rules! bijective_higher_ranked_trait {
<__ as LowerForLt<
$lt,
$($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic),*
>>::T;
@@ -226,7 +175,7 @@ macro_rules! bijective_higher_ranked_trait {
>: RaiseForLt<
$lt,
$($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic),*
> $(+ $($provides)+)?
where
@@ -244,7 +193,7 @@ macro_rules! bijective_higher_ranked_trait {
__: RaiseForLt<
$lt,
$($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic),*
> $(+ $($provides)+)?,
$($($bound)*)?
@@ -255,13 +204,15 @@ macro_rules! bijective_higher_ranked_trait {
<__ as RaiseForLt<
$lt,
$($lifetimes,)*
- &$lt ($(&$lifetimes (),)* $($generic),*),
+ &$lt ($(&$lifetimes (),)* $(*const $generic,)*),
$($generic),*
>>::HigherRanked;
}
};
}
+use core::marker::PhantomData;
+
#[doc(inline)]
pub use bijective_higher_ranked_trait;
@@ -271,7 +222,7 @@ pub use bijective_higher_ranked_trait;
macro_rules! bijective_higher_ranked_type {
{
$(#[$($meta:tt)*])*
- $vis:vis type $name:ident[
+ $vis:vis $(for[$($extra_lt:lifetime)*])? type $name:ident[
$($ctx:lifetime),*
][
$($generic:ident),*
@@ -285,12 +236,12 @@ macro_rules! bijective_higher_ranked_type {
} => {
$(#[$($meta)*])*
$vis struct $name<
- $($type_class_lifetime,)*
+ $($ctx,)*
$($generic: ?Sized,)*
$($($forwarding_generic: ?Sized),*)?
>(
core::marker::PhantomData<fn() -> (
- $(&$type_class_lifetime (),)*
+ $(&$ctx (),)*
$(*const $generic,)*
$($(*const $forwarding_generic,)*)?
)>
@@ -298,6 +249,7 @@ macro_rules! bijective_higher_ranked_type {
impl<
$lt,
+ $($($extra_lt,)*)?
$($ctx,)*
$($generic,)*
$($($forwarding_generic),*)?
@@ -310,7 +262,7 @@ macro_rules! bijective_higher_ranked_type {
),
$($type_class_generic),*
> for $name<
- $($type_class_lifetime,)*
+ $($ctx,)*
$($generic,)*
$($($forwarding_generic),*)?
>
@@ -322,7 +274,7 @@ macro_rules! bijective_higher_ranked_type {
&$lt (
$(&$forward_lt (),)*
$(*const $forward_generic,)*
- )
+ ),
$($forward_generic,)*
>,
)*)?
@@ -333,6 +285,7 @@ macro_rules! bijective_higher_ranked_type {
impl<
$lt,
+ $($($extra_lt,)*)?
$($ctx,)*
$($generic,)*
$($($forwarding_generic),*)?
@@ -353,14 +306,14 @@ macro_rules! bijective_higher_ranked_type {
&$lt (
$(&$forward_lt (),)*
$(*const $forward_generic,)*
- )
+ ),
$($forward_generic,)*
>,
)*)?
$($($bound)*)?
{
type HigherRanked = $name<
- $($type_class_lifetime,)*
+ $($ctx,)*
$($generic,)*
$($(
<$forwarding_generic as $type_class::RaiseForLt<
@@ -369,7 +322,7 @@ macro_rules! bijective_higher_ranked_type {
&$lt (
$(&$forward_lt (),)*
$(*const $forward_generic,)*
- )
+ ),
$($forward_generic,)*
>>::HigherRanked
),*)?
@@ -377,7 +330,7 @@ macro_rules! bijective_higher_ranked_type {
}
};
{
- $vis:vis type [
+ $vis:vis $(for[$($extra_lt:lifetime)*])? type [
$($ctx:lifetime),*
][
$($generic:ident),*
@@ -391,7 +344,7 @@ macro_rules! bijective_higher_ranked_type {
} => {
const _: () = {
$crate::hkt::bijective_higher_ranked_type! {
- $vis type __HigherRanked[
+ $vis $(for[$($extra_lt)*])? type __HigherRanked[
$($ctx),*
][
$($generic),*
@@ -407,7 +360,7 @@ macro_rules! bijective_higher_ranked_type {
};
{
$(#[$($meta:tt)*])*
- $vis:vis type $name:ident[
+ $vis:vis $(for[$($extra_lt:lifetime)*])? type $name:ident[
$($ctx:lifetime),*
][
$($generic:ident),*
@@ -420,7 +373,7 @@ macro_rules! bijective_higher_ranked_type {
} => {
$crate::hkt::bijective_higher_ranked_type! {
$(#[$($meta)*])*
- $vis type $name[
+ $vis $(for[$($extra_lt)*])? type $name[
$($ctx),*
][
$($generic),*
@@ -438,70 +391,70 @@ macro_rules! bijective_higher_ranked_type {
#[doc(inline)]
pub use bijective_higher_ranked_type;
-higher_ranked_trait! {
- pub type class AnySend['ctx]: [for<'lt> Send]
+bijective_higher_ranked_trait! {
+ pub type class AnySizedSend[][]: [for<'lt> Send + Sized]
}
-#[cfg(test)]
-mod test {
- use super::*;
-
- /// Some trait with two lifetimes and a generic.
- trait Demo<'lt, 'ctx, T: Send + 'lt> {
- fn add(&self, x: &'lt &'ctx i32) -> i32;
- }
-
- impl<'lt, 'ctx, T: Send + 'lt> Demo<'lt, 'ctx, T> for i32 {
- fn add(&self, x: &'lt &'ctx i32) -> i32 {
- self + **x
- }
- }
-
- impl<'lt, 'ctx, T: Send + 'lt> Demo<'lt, 'ctx, T> for &'lt (dyn Demo<'lt, 'ctx, T> + 'lt) {
- fn add(&self, x: &'lt &'ctx i32) -> i32 {
- (**self).add(x)
- }
- }
-
- // Higher-ranked trait that requires the "true" type to implement Demo.
- higher_ranked_trait! {
- type class Any['ctx, T]: [for<'lt> Demo<'lt, 'ctx, T>]
- where {
- T: Send,
- }
- for where {
- T: 'lt
- }
- }
-
- // Higher-ranked type with a "true" type of a borrow of a trait object.
- // The complex part to support here is the `+ 'lt`.
- // This entire module is specialized to support this usecase because that is what treaty needs
- // for it's API.
- higher_ranked_type! {
- type X['ctx, T]: (Any)[T]
- where {
- T: Send,
- } = for<'lt> &'lt (dyn Demo<'lt, 'ctx, T> + 'lt)
- }
-
- // We bound the generic T by the higher-ranked trait Any.
- //
- // We then inject a 'lt into the higher-ranked type to get a "true" type.
- fn demo<'lt, 'ctx, T: Any::Trait<'ctx, i32>>(x: Any::T<'lt, 'ctx, T, i32>, y: &'lt &'ctx i32) {
- assert_eq!(x.add(y), 10);
- }
-
- #[test]
- fn can_use_hkt() {
- let ctx = 2;
- let ctx = &ctx;
-
- {
- // The lifetimes here can't be 'static because local isn't static even though z could be.
- let local = &ctx;
- let z: &dyn Demo<'_, '_, i32> = &8i32;
- demo::<X<'_, i32>>(z, local);
- }
- }
-}
+// #[cfg(test)]
+// mod test {
+// use super::*;
+//
+// /// Some trait with two lifetimes and a generic.
+// trait Demo<'lt, 'ctx, T: Send + 'lt> {
+// fn add(&self, x: &'lt &'ctx i32) -> i32;
+// }
+//
+// impl<'lt, 'ctx, T: Send + 'lt> Demo<'lt, 'ctx, T> for i32 {
+// fn add(&self, x: &'lt &'ctx i32) -> i32 {
+// self + **x
+// }
+// }
+//
+// impl<'lt, 'ctx, T: Send + 'lt> Demo<'lt, 'ctx, T> for &'lt (dyn Demo<'lt, 'ctx, T> + 'lt) {
+// fn add(&self, x: &'lt &'ctx i32) -> i32 {
+// (**self).add(x)
+// }
+// }
+//
+// // Higher-ranked trait that requires the "true" type to implement Demo.
+// bijective_higher_ranked_trait! {
+// type class Any['ctx, T]: [for<'lt> Demo<'lt, 'ctx, T>]
+// where {
+// T: Send,
+// }
+// for where {
+// T: 'lt
+// }
+// }
+//
+// // Higher-ranked type with a "true" type of a borrow of a trait object.
+// // The complex part to support here is the `+ 'lt`.
+// // This entire module is specialized to support this usecase because that is what treaty needs
+// // for it's API.
+// higher_ranked_type! {
+// type X['ctx, T]: (Any)[T]
+// where {
+// T: Send,
+// } = for<'lt> &'lt (dyn Demo<'lt, 'ctx, T> + 'lt)
+// }
+//
+// // We bound the generic T by the higher-ranked trait Any.
+// //
+// // We then inject a 'lt into the higher-ranked type to get a "true" type.
+// fn demo<'lt, 'ctx, T: Any::Trait<'ctx, i32>>(x: Any::T<'lt, 'ctx, T, i32>, y: &'lt &'ctx i32) {
+// assert_eq!(x.add(y), 10);
+// }
+//
+// #[test]
+// fn can_use_hkt() {
+// let ctx = 2;
+// let ctx = &ctx;
+//
+// {
+// // The lifetimes here can't be 'static because local isn't static even though z could be.
+// let local = &ctx;
+// let z: &dyn Demo<'_, '_, i32> = &8i32;
+// demo::<X<'_, i32>>(z, local);
+// }
+// }
+// }
diff --git a/src/lib.rs b/src/lib.rs
index 043f6b7..21f642c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,27 +15,13 @@ pub mod protocol;
pub mod symbol;
mod transform;
mod walk;
-
-#[cfg(any(test, feature = "mock"))]
-pub mod mock;
-
-// pub use build::Build;
-// pub use build::Builder;
-//
-// pub use walk::Walk;
-// pub use walk::Walker;
-
-use core::ops::ControlFlow;
+pub mod macros;
pub use build::*;
-use effect::{Effect, Future};
-// use protocol::{visitor::tag::TagError, Visitor};
-use symbol::Symbol;
pub use transform::*;
pub use walk::*;
-// #[doc(hidden)]
-pub mod macros;
+use symbol::Symbol;
pub mod never {
mod sealed {
@@ -93,7 +79,7 @@ macro_rules! Walk {
),* $(,)?}
} => {
const _: () = {
- impl<'ctx, M: 'ctx, E: $crate::effect::Effect<'ctx>> $crate::Walk<'ctx, M, E> for &'ctx $name {
+ impl<'ctx, M: 'ctx, E: $crate::effect::Effect> $crate::Walk<'ctx, M, E> for &'ctx $name {
type Walker = $crate::walkers::core::r#struct::StructWalker<'ctx, $name, Info, M, E>;
fn into_walker(self) -> Self::Walker {
@@ -109,12 +95,13 @@ macro_rules! Walk {
$vis enum Info {}
#[derive(Debug)]
- #[allow(non_camel_case_types)]
+ #[allow(non_camel_case_types, unused)]
enum FieldErrorKind<'ctx> {$(
$field($crate::walkers::core::key_value::KeyValueError<$crate::never::Never, <&'ctx $type as $crate::WalkerTypes>::Error>)
),*}
#[derive(Debug)]
+ #[allow(unused)]
$vis struct FieldError<'ctx>(FieldErrorKind<'ctx>);
impl<'ctx, M: 'ctx> $crate::walkers::core::r#struct::StructTypeInfo<'ctx, M> for Info {
@@ -125,11 +112,11 @@ macro_rules! Walk {
type T = $name;
#[allow(unreachable_code, non_snake_case, non_upper_case_globals, non_camel_case_types)]
- fn walk_field<'a, E: $crate::effect::Effect<'ctx>>(
+ fn walk_field<'a, E: $crate::effect::Effect>(
index: usize,
value: &'ctx Self::T,
visitor: $crate::protocol::Visitor<'a, 'ctx>,
- ) -> $crate::effect::Future<'a, 'ctx, Result<$crate::Flow, Self::FieldError>, E> {
+ ) -> $crate::effect::Future<'a, Result<$crate::Flow, Self::FieldError>, E> {
mod fields {
enum Fields {$($field),*}
@@ -173,41 +160,41 @@ Walk! {
}
}
-#[cfg(test)]
-mod test {
- use crate::effect::{BlockOn, Blocking, Spin};
-
- use super::*;
- use macro_rules_attribute::derive;
-
- #[derive(Walk!)]
- struct Demo {
- a: bool,
- b: bool,
- other: Other,
- }
-
- #[derive(Walk!)]
- struct Other {
- value: bool,
- }
-
- #[test]
- fn demo() {
- let value = Demo {
- a: true,
- b: false,
- other: Other { value: true },
- };
-
- let walker = Walk::<DefaultMode, Blocking>::into_walker(&value);
- let mut visitor = builders::debug::Visitor::<Blocking>::new();
-
- dbg!(Spin::block_on(Walker::<Blocking>::walk(
- walker,
- &mut visitor
- )));
-
- todo!();
- }
-}
+// #[cfg(test)]
+// mod test {
+// use crate::effect::{BlockOn, Blocking, Spin};
+//
+// use super::*;
+// use macro_rules_attribute::derive;
+//
+// #[derive(Walk!)]
+// struct Demo {
+// a: bool,
+// b: bool,
+// other: Other,
+// }
+//
+// #[derive(Walk!)]
+// struct Other {
+// value: bool,
+// }
+//
+// #[test]
+// fn demo() {
+// let value = Demo {
+// a: true,
+// b: false,
+// other: Other { value: true },
+// };
+//
+// let walker = Walk::<DefaultMode, Blocking>::into_walker(&value);
+// let mut visitor = builders::debug::Visitor::<Blocking>::new();
+//
+// dbg!(Spin::block_on(Walker::<Blocking>::walk(
+// walker,
+// &mut visitor
+// )));
+//
+// todo!();
+// }
+// }
diff --git a/src/mock.rs b/src/mock.rs
index 89a7a64..e69de29 100644
--- a/src/mock.rs
+++ b/src/mock.rs
@@ -1,81 +0,0 @@
-use core::{
- any::{Any, TypeId},
- ops::Deref,
-};
-use std::{
- collections::HashMap,
- sync::{Mutex, MutexGuard, OnceLock, RwLock},
-};
-
-pub mod builder;
-pub mod protocol;
-
-pub struct StaticTypeMap {
- map: OnceLock<RwLock<HashMap<TypeId, &'static (dyn Any + Send + Sync)>>>,
-}
-
-impl StaticTypeMap {
- pub const fn new() -> Self {
- Self {
- map: OnceLock::new(),
- }
- }
-
- pub fn get_or_init<T: Send + Sync + 'static, F: FnOnce() -> T>(&self, f: F) -> &'static T {
- let map_init = || RwLock::new(HashMap::new());
-
- let map = self.map.get_or_init(map_init).read().unwrap();
-
- if let Some(once) = map.get(&TypeId::of::<T>()) {
- return once.downcast_ref::<T>().unwrap();
- }
-
- drop(map);
-
- let mut map = self.map.get_or_init(map_init).write().unwrap();
- let once = &*Box::leak(Box::new(f()));
- map.insert(TypeId::of::<T>(), once);
-
- once
- }
-}
-
-pub struct ContextLock<T> {
- lock: Mutex<T>,
- checkpoint: fn(&T),
-}
-
-impl<T> ContextLock<T> {
- pub const fn new(context: T, checkpoint: fn(&T)) -> Self {
- Self {
- lock: Mutex::new(context),
- checkpoint,
- }
- }
-
- pub fn lock(&self) -> ContextGuard<'_, T> {
- ContextGuard {
- lock: self,
- guard: self.lock.lock().unwrap(),
- }
- }
-}
-
-pub struct ContextGuard<'a, T> {
- lock: &'a ContextLock<T>,
- guard: MutexGuard<'a, T>,
-}
-
-impl<'a, T> Drop for ContextGuard<'a, T> {
- fn drop(&mut self) {
- (self.lock.checkpoint)(&*self.guard)
- }
-}
-
-impl<'a, T> Deref for ContextGuard<'a, T> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.guard
- }
-}
diff --git a/src/mock/protocol.rs b/src/mock/protocol.rs
deleted file mode 100644
index 422fa94..0000000
--- a/src/mock/protocol.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-pub mod tag;
-pub mod value;
diff --git a/src/protocol/visitor/recoverable.rs b/src/protocol/visitor/recoverable.rs
index a3a9d65..90c671b 100644
--- a/src/protocol/visitor/recoverable.rs
+++ b/src/protocol/visitor/recoverable.rs
@@ -1,20 +1,14 @@
use crate::{
- any::{TypeName, WithContextLt},
- bijective_higher_ranked_type,
- effect::{Effect, Future},
- higher_ranked_type,
- hkt::AnySend,
- protocol::{walker::hint::HintMeta, Visitor},
- Flow,
+ any::{TypeName, WithContextLt}, bijective_higher_ranked_type, effect::{Effect, Future}, hkt::AnySizedSend, protocol::{walker::hint::HintMeta, Visitor}, Flow
};
use super::Status;
-pub trait Recoverable<'ctx, E: Effect<'ctx>> {
+pub trait Recoverable<'ctx, E: Effect> {
fn visit<'a>(
&'a mut self,
scope: DynRecoverableScope<'a, 'ctx, E>,
- ) -> Future<'a, 'ctx, Flow, E>;
+ ) -> Future<'a, Flow, E>;
}
bijective_higher_ranked_type! {
@@ -22,7 +16,7 @@ bijective_higher_ranked_type! {
for<'a>
(dyn Recoverable<'ctx, E> + Send + 'a)
where {
- E: Effect<'ctx>
+ E: Effect
}
}
@@ -31,30 +25,30 @@ bijective_higher_ranked_type! {
for<'ctx>
(DynRecoverable<'ctx, E>)
where {
- E: Effect<'ctx>
+ E: Effect
}
}
-pub trait RecoverableScope<'ctx, E: Effect<'ctx>> {
- fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E>;
+pub trait RecoverableScope<'ctx, E: Effect> {
+ fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E>;
}
pub type DynRecoverableScope<'a, 'ctx, E> = &'a mut (dyn RecoverableScope<'ctx, E> + Send + 'a);
-higher_ranked_type! {
- pub type RecoverableKnownHkt['ctx]: (AnySend) = for<'lt> ()
+bijective_higher_ranked_type! {
+ pub type RecoverableKnownHkt[][]: AnySizedSend[][] for<'lt> (())
}
-impl<'ctx, E: Effect<'ctx>> HintMeta<'ctx> for DynRecoverable<'ctx, E> {
- type Known = RecoverableKnownHkt<'ctx>;
+impl<'ctx, E: Effect> HintMeta<'ctx> for DynRecoverable<'ctx, E> {
+ type Known = RecoverableKnownHkt;
type Hint = ();
}
-pub fn visit_recoverable<'a, 'ctx, E: Effect<'ctx>>(
+pub fn visit_recoverable<'a, 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
scope: DynRecoverableScope<'a, 'ctx, E>,
-) -> Future<'a, 'ctx, Status, E> {
+) -> Future<'a, Status, 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 {
diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs
index 123e187..343dcb9 100644
--- a/src/protocol/visitor/request_hint.rs
+++ b/src/protocol/visitor/request_hint.rs
@@ -7,12 +7,12 @@ use crate::{
};
/// Protocol for requesting a hint from a visitor.
-pub trait RequestHint<'ctx, E: Effect<'ctx>> {
+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, 'ctx, Flow, E>;
+ fn request_hint<'a>(&'a mut self, walker: Walker<'a, 'ctx>) -> Future<'a, Flow, E>;
}
bijective_higher_ranked_type! {
@@ -20,7 +20,7 @@ bijective_higher_ranked_type! {
for<'a>
(dyn RequestHint<'ctx, E> + Send + 'a)
where {
- E: Effect<'ctx>
+ E: Effect
}
}
@@ -29,7 +29,7 @@ bijective_higher_ranked_type! {
for<'ctx>
(DynRequestHint<'ctx, E>)
where {
- E: Effect<'ctx>
+ E: Effect
}
}
@@ -40,10 +40,10 @@ bijective_higher_ranked_type! {
/// If [`Flow::Done`] is returned then the visitor doesn't need any more information and the walker
/// should stop walking.
/// If [`Flow::Break`] is returned then there was an error and the walker should stop walking.
-pub fn visit_request_hint<'a, 'ctx, E: Effect<'ctx>>(
+pub fn visit_request_hint<'a, 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
walker: Walker<'a, 'ctx>,
-) -> Future<'a, 'ctx, Flow, E> {
+) -> Future<'a, Flow, 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)
diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs
index 88fd248..25ba8dd 100644
--- a/src/protocol/visitor/sequence.rs
+++ b/src/protocol/visitor/sequence.rs
@@ -2,16 +2,15 @@ use crate::{
any::{TypeName, WithContextLt},
bijective_higher_ranked_type,
effect::{Effect, Future},
- higher_ranked_type,
- hkt::AnySend,
+ hkt::AnySizedSend,
protocol::{walker::hint::HintMeta, Visitor},
Flow,
};
use super::Status;
-pub trait Sequence<'ctx, E: Effect<'ctx>> {
- fn visit<'a>(&'a mut self, scope: DynSequenceScope<'a, 'ctx, E>) -> Future<'a, 'ctx, Flow, E>;
+pub trait Sequence<'ctx, E: Effect> {
+ fn visit<'a>(&'a mut self, scope: DynSequenceScope<'a, 'ctx, E>) -> Future<'a, Flow, E>;
}
bijective_higher_ranked_type! {
@@ -19,7 +18,7 @@ bijective_higher_ranked_type! {
for<'a>
(dyn Sequence<'ctx, E> + Send + 'a)
where {
- E: Effect<'ctx>
+ E: Effect
}
}
@@ -28,20 +27,20 @@ bijective_higher_ranked_type! {
for<'ctx>
(DynSequence<'ctx, E>)
where {
- E: Effect<'ctx>
+ E: Effect
}
}
-pub trait SequenceScope<'ctx, E: Effect<'ctx>> {
- fn size_hint<'a>(&'a mut self) -> Future<'a, 'ctx, (usize, Option<usize>), E>;
+pub trait SequenceScope<'ctx, E: Effect> {
+ fn size_hint(&mut self) -> Future<'_, (usize, Option<usize>), E>;
- fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E>;
+ fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E>;
}
pub type DynSequenceScope<'a, 'ctx, E> = &'a mut (dyn SequenceScope<'ctx, E> + Send + 'a);
-higher_ranked_type! {
- pub type SequenceKnownHkt['ctx]: (AnySend) = for<'lt> SequenceKnown
+bijective_higher_ranked_type! {
+ pub type SequenceKnownHkt[][]: AnySizedSend[][] for<'lt> (SequenceKnown)
}
#[derive(Default)]
@@ -53,16 +52,16 @@ pub struct SequenceHint {
pub len: (usize, Option<usize>),
}
-impl<'ctx, E: Effect<'ctx>> HintMeta<'ctx> for DynSequence<'ctx, E> {
- type Known = SequenceKnownHkt<'ctx>;
+impl<'ctx, E: Effect> HintMeta<'ctx> for DynSequence<'ctx, E> {
+ type Known = SequenceKnownHkt;
type Hint = SequenceHint;
}
-pub fn visit_sequence<'a, 'ctx, E: Effect<'ctx>>(
+pub fn visit_sequence<'a, 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
scope: DynSequenceScope<'a, 'ctx, E>,
-) -> Future<'a, 'ctx, Status, E> {
+) -> Future<'a, Status, 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 {
diff --git a/src/protocol/visitor/tag.rs b/src/protocol/visitor/tag.rs
index 0bd5750..4d0bfb2 100644
--- a/src/protocol/visitor/tag.rs
+++ b/src/protocol/visitor/tag.rs
@@ -2,8 +2,7 @@ use crate::{
any::{TypeName, WithContextLt},
bijective_higher_ranked_type,
effect::{Effect, Future},
- higher_ranked_type,
- hkt::AnySend,
+ hkt::AnySizedSend,
protocol::{walker::hint::HintMeta, Visitor},
symbol::Symbol,
DynWalker, DynWalkerAdapter, DynWalkerError, Flow, WalkerTypes,
@@ -39,12 +38,12 @@ impl TagKind for TagDyn {
}
}
-pub trait Tag<'ctx, K: TagKind, E: Effect<'ctx>> {
+pub trait Tag<'ctx, K: TagKind, E: Effect> {
fn visit<'a>(
&'a mut self,
kind: K,
walker: DynWalker<'a, 'ctx, E>,
- ) -> Future<'a, 'ctx, K::Flow, E>;
+ ) -> Future<'a, K::Flow, E>;
}
bijective_higher_ranked_type! {
@@ -52,7 +51,7 @@ bijective_higher_ranked_type! {
for<'a>
(dyn Tag<'ctx, K, E> + Send + 'a)
where {
- E: Effect<'ctx>,
+ E: Effect,
K: TagKind,
}
}
@@ -62,13 +61,13 @@ bijective_higher_ranked_type! {
for<'ctx>
(DynTag<'ctx, K, E>)
where {
- E: Effect<'ctx>,
+ E: Effect,
K: TagKind,
}
}
-higher_ranked_type! {
- pub type TagKnownHkt['ctx]: (AnySend) = for<'lt> TagKnown
+bijective_higher_ranked_type! {
+ pub type TagKnownHkt[][]: AnySizedSend[][] for<'lt> (TagKnown)
}
pub struct TagKnown {
@@ -80,7 +79,7 @@ pub struct TagHint<K> {
}
impl<'ctx, K, E> HintMeta<'ctx> for DynTag<'ctx, K, E> {
- type Known = TagKnownHkt<'ctx>;
+ type Known = TagKnownHkt;
type Hint = TagHint<K>;
}
@@ -99,6 +98,7 @@ pub enum TagErrorKind<E> {
}
#[derive(Debug)]
+#[allow(unused)]
pub struct TagError<E> {
symbol: Symbol,
err: TagErrorKind<E>,
@@ -134,11 +134,11 @@ impl<E> TagError<E> {
}
}
-pub fn visit_tag<'a, 'ctx: 'a, K: TagKind, E: Effect<'ctx>, W: crate::Walker<'ctx, E> + 'a>(
+pub fn visit_tag<'a, 'ctx: 'a, K: TagKind, E: Effect, W: crate::Walker<'ctx, E> + 'a>(
kind: K,
visitor: Visitor<'a, 'ctx>,
walker: W,
-) -> Future<'a, 'ctx, Result<Status<W>, TagError<W::Error>>, E>
+) -> Future<'a, Result<Status<W>, TagError<W::Error>>, E>
where
W: WalkerTypes,
{
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index 419964b..43a845f 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -6,18 +6,17 @@ use crate::{
any::{TypeName, WithContextLt},
bijective_higher_ranked_type,
effect::{Effect, Future},
- higher_ranked_type,
- hkt::AnySend,
+ hkt::AnySizedSend,
protocol::{walker::hint::HintMeta, Visitor},
Flow,
};
-use super::{recoverable::Recoverable, Status};
+use super::Status;
/// Trait object for the [`Value`] protocol.
///
/// Types implementing the [`Value`] protocol will implement this trait.
-pub trait Value<'ctx, T: WithContextLt::MemberType<'ctx>, E: Effect<'ctx>> {
+pub trait Value<'ctx, T: WithContextLt::MemberType<'ctx>, E: Effect> {
/// Visit a value of type `T`.
///
/// Use this to give a value to a visitor. Its expected that a walker
@@ -27,7 +26,9 @@ pub trait Value<'ctx, T: WithContextLt::MemberType<'ctx>, E: Effect<'ctx>> {
/// 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, 'ctx, Flow, E>;
+ fn visit<'a>(&'a mut self, value: WithContextLt::T<'a, 'ctx, T>) -> Future<'a, Flow, E>
+ where
+ 'ctx: 'a;
}
bijective_higher_ranked_type! {
@@ -35,7 +36,7 @@ bijective_higher_ranked_type! {
for<'a>
(dyn Value<'ctx, T, E> + Send + 'a)
where {
- E: Effect<'ctx>,
+ E: Effect,
T: ?Sized + WithContextLt::MemberType<'ctx> + 'ctx
}
}
@@ -46,26 +47,28 @@ bijective_higher_ranked_type! {
(DynValue<'ctx, TypeName::T<'ctx, T>, E>)
(DynValue<'ctx, T, E>)
where {
- E: Effect<'ctx>,
+ E: Effect,
T: ?Sized,
}
}
-higher_ranked_type! {
- pub type ValueKnownHkt['ctx]: (AnySend) = for<'lt> ()
+pub struct ValueKnown;
+
+bijective_higher_ranked_type! {
+ pub type ValueKnownHkt[][]: AnySizedSend[][] for<'lt> (ValueKnown)
}
// This enrolls the Value protocol into the walker hint system.
-impl<'a, 'ctx: 'a, T, E: Effect<'ctx>> HintMeta<'ctx> for DynValue<'ctx, T, E> {
- type Known = ValueKnownHkt<'ctx>;
+impl<'a, 'ctx: 'a, T, E: Effect> HintMeta<'ctx> for DynValue<'ctx, T, E> {
+ type Known = ValueKnownHkt;
type Hint = ();
}
-pub fn visit_value<'a, 'ctx, T: WithContextLt::LowerType<'a, 'ctx> + 'ctx, E: Effect<'ctx>>(
+pub fn visit_value<'a, 'ctx, T: WithContextLt::LowerType<'a, 'ctx> + 'ctx, E: Effect>(
visitor: Visitor<'a, 'ctx>,
value: T,
-) -> Future<'a, 'ctx, Status, E>
+) -> Future<'a, Status, E>
where
WithContextLt::HigherRanked<'a, 'ctx, T>: TypeName::LowerType<'ctx> + Sized,
{
@@ -115,12 +118,13 @@ mod test {
impl<'ctx, E> Value<'ctx, DynOwnedStatic<i32>, E> for Visitor<E>
where
- E: Effect<'ctx>,
+ E: Effect,
{
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<i32>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where 'ctx: 'a{
E::wrap(async move {
self.0 = Some(value);
Flow::Continue
@@ -130,12 +134,15 @@ mod test {
impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, i32>, E> for Visitor<E>
where
- E: Effect<'ctx>,
+ E: Effect,
{
fn visit<'a>(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, i32>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where
+ 'ctx: 'a
+ {
E::wrap(async {
self.0 = Some(*value);
Flow::Continue
@@ -147,12 +154,12 @@ mod test {
impl['ctx, E] Visitor<E> = [
DynValue<'ctx, DynOwnedStatic<i32>, E>,
DynValue<'ctx, DynBorrowedStatic<'ctx, i32>, E>,
- ] where E: Effect<'ctx>,
+ ] where E: Effect,
}
let mut v = Visitor::<Blocking>(None, PhantomData);
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- Spin::block_on(
+ let _ = Spin::block_on(
object
.upcast_mut::<DynValue<'_, DynOwnedStatic<i32>, Blocking>>()
.unwrap()
@@ -162,7 +169,7 @@ mod test {
assert_eq!(v.0, Some(42));
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- Spin::block_on(
+ let _ = Spin::block_on(
object
.upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, i32>, Blocking>>()
.unwrap()
@@ -178,12 +185,13 @@ mod test {
impl<'ctx, E> Value<'ctx, DynBorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E>
where
- E: Effect<'ctx>,
+ E: Effect,
{
fn visit<'a>(
&'a mut self,
BorrowedMutStatic(value): BorrowedMutStatic<'ctx, String>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where 'ctx: 'a{
E::wrap(async {
self.0 = Some(value);
@@ -195,14 +203,14 @@ mod test {
any_trait! {
impl['ctx, E] Visitor<'ctx, E> = [
DynValue<'ctx, DynBorrowedMutStatic<'ctx, String>, E>,
- ] where E: Effect<'ctx>
+ ] where E: Effect
}
let mut v = Visitor::<Blocking>(None, PhantomData);
let mut y = String::from("abc");
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- Spin::block_on(
+ let _ = Spin::block_on(
object
.upcast_mut::<DynValue<'_, DynBorrowedMutStatic<'_, _>, Blocking>>()
.unwrap()
@@ -219,12 +227,13 @@ mod test {
impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E>
where
- E: Effect<'ctx>,
+ E: Effect,
{
fn visit<'a>(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, str>,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E>
+ where 'ctx: 'a{
E::wrap(async {
self.0 = Some(value);
Flow::Continue
@@ -235,14 +244,14 @@ mod test {
any_trait! {
impl['ctx, E] Visitor<'ctx, E> = [
DynValue<'ctx, DynBorrowedStatic<'ctx, str>, E>,
- ] where E: Effect<'ctx>
+ ] where E: Effect
}
let mut v = Visitor::<Blocking>(None, PhantomData);
let y = String::from("abc");
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
- Spin::block_on(
+ let _ = Spin::block_on(
object
.upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, str>, Blocking>>()
.unwrap()
diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs
index e7d41c6..b5ebd37 100644
--- a/src/protocol/walker/hint.rs
+++ b/src/protocol/walker/hint.rs
@@ -8,7 +8,7 @@ use crate::{
any::{TypeName, WithContextLt},
bijective_higher_ranked_type,
effect::{Effect, Future},
- hkt::AnySend,
+ hkt::AnySizedSend,
protocol::Visitor,
Flow,
};
@@ -21,16 +21,16 @@ pub trait HintMeta<'ctx> {
///
/// This should be information easy to get without changing the state of the walker
/// in an irreversible way.
- type Known: AnySend::Trait<'ctx>;
+ type Known: AnySizedSend::MemberType;
/// Extra information the visitor can give to the walker about what it is expecting.
type Hint;
}
-pub type Known<'a, 'ctx, Protocol> = AnySend::T<'a, 'ctx, <Protocol as HintMeta<'ctx>>::Known>;
+pub type Known<'a, 'ctx, Protocol> = AnySizedSend::T<'a, <Protocol as HintMeta<'ctx>>::Known>;
/// Object implementing the [`Hint`] protocol.
-pub trait Hint<'ctx, Protocol: ?Sized + HintMeta<'ctx>, E: Effect<'ctx>> {
+pub trait Hint<'ctx, Protocol: ?Sized + HintMeta<'ctx>, E: Effect> {
/// Hint to the walker to use the `P` protocol.
///
/// This should only be called once per [`RequestHint`].
@@ -38,13 +38,13 @@ pub trait Hint<'ctx, Protocol: ?Sized + HintMeta<'ctx>, E: Effect<'ctx>> {
&'a mut self,
visitor: Visitor<'a, 'ctx>,
hint: <Protocol as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E>;
+ ) -> Future<'a, Flow, E>;
/// Ask the walker for information about it's support of the protocol.
fn known<'a>(
&'a mut self,
hint: &'a <Protocol as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, Protocol>, ()>, E>;
+ ) -> Future<'a, Result<Known<'a, 'ctx, Protocol>, ()>, E>;
}
bijective_higher_ranked_type! {
@@ -52,7 +52,7 @@ bijective_higher_ranked_type! {
for<'a>
(dyn Hint<'ctx, Protocol, E> + Send + 'a)
where {
- E: Effect<'ctx>,
+ E: Effect,
Protocol: ?Sized + WithContextLt::MemberType<'ctx> + 'ctx,
}
}
@@ -63,75 +63,74 @@ bijective_higher_ranked_type! {
(DynHint<'ctx, TypeName::T<'ctx, Protocol>, E>)
(DynHint<'ctx, Protocol, E>)
where {
- E: Effect<'ctx>,
+ E: Effect,
Protocol: ?Sized,
}
}
-#[cfg(test)]
-mod test {
- use crate::{
- effect::{BlockOn, Blocking, Spin},
- higher_ranked_type,
- };
-
- use super::*;
-
- #[test]
- fn demo() {
- struct X<'ctx>(&'ctx mut i32);
-
- #[derive(Debug)]
- struct Y;
-
- bijective_higher_ranked_type! {
- type DynY['ctx][]: WithContextLt['ctx][] for<'a> (Y)
- }
-
- bijective_higher_ranked_type! {
- type [][]: TypeName[][] for<'ctx> (DynY<'ctx>)
- }
-
- impl<'ctx, E: Effect<'ctx>> Hint<'ctx, DynY<'ctx>, E> for X<'ctx> {
- fn hint<'a>(
- &'a mut self,
- _visitor: Visitor<'a, 'ctx>,
- _hint: <DynY<'ctx> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
- todo!()
- }
-
- fn known<'a>(
- &'a mut self,
- _hint: &'a <DynY<'ctx> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynY<'ctx>>, ()>, E> {
- E::ready(Ok(&mut *self.0))
- }
- }
-
- higher_ranked_type! {
- type KnownHkt['ctx]: (AnySend) = for<'lt> &'lt mut i32
- }
-
- impl<'ctx> HintMeta<'ctx> for DynY<'ctx> {
- type Known = KnownHkt<'ctx>;
-
- type Hint = ();
- }
-
- let mut z = 42;
- let mut x = X(&mut z);
- let y: &mut WithContextLt::T<'_, '_, DynHint<'_, DynY<'_>, Blocking>> = &mut x;
-
- fn id<'a, 'ctx, T: ?Sized + TypeName::LowerType<'ctx>>(_x: &WithContextLt::T<'a, 'ctx, T>) {
- }
- id::<DynHint<'_, DynY<'_>, Blocking>>(y);
-
- let x = Spin::block_on(y.known(&()));
- match x {
- Ok(value) => *value += 1,
- Err(_) => todo!(),
- }
- assert_eq!(z, 43);
- }
-}
+// #[cfg(test)]
+// mod test {
+// use crate::{
+// effect::{BlockOn, Blocking, Spin},
+// };
+//
+// use super::*;
+//
+// #[test]
+// fn demo() {
+// struct X<'ctx>(&'ctx mut i32);
+//
+// #[derive(Debug)]
+// struct Y;
+//
+// bijective_higher_ranked_type! {
+// type DynY['ctx][]: WithContextLt['ctx][] for<'a> (Y)
+// }
+//
+// bijective_higher_ranked_type! {
+// type [][]: TypeName[][] for<'ctx> (DynY<'ctx>)
+// }
+//
+// impl<'ctx, E: Effect<'ctx>> Hint<'ctx, DynY<'ctx>, E> for X<'ctx> {
+// fn hint<'a>(
+// &'a mut self,
+// _visitor: Visitor<'a, 'ctx>,
+// _hint: <DynY<'ctx> as HintMeta<'ctx>>::Hint,
+// ) -> Future<'a, 'ctx, Flow, E> {
+// todo!()
+// }
+//
+// fn known<'a>(
+// &'a mut self,
+// _hint: &'a <DynY<'ctx> as HintMeta<'ctx>>::Hint,
+// ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynY<'ctx>>, ()>, E> {
+// E::ready(Ok(&mut *self.0))
+// }
+// }
+//
+// higher_ranked_type! {
+// type KnownHkt['ctx]: (AnySend) = for<'lt> &'lt mut i32
+// }
+//
+// impl<'ctx> HintMeta<'ctx> for DynY<'ctx> {
+// type Known = KnownHkt<'ctx>;
+//
+// type Hint = ();
+// }
+//
+// let mut z = 42;
+// let mut x = X(&mut z);
+// let y: &mut WithContextLt::T<'_, '_, DynHint<'_, DynY<'_>, Blocking>> = &mut x;
+//
+// fn id<'a, 'ctx, T: ?Sized + TypeName::LowerType<'ctx>>(_x: &WithContextLt::T<'a, 'ctx, T>) {
+// }
+// id::<DynHint<'_, DynY<'_>, Blocking>>(y);
+//
+// let x = Spin::block_on(y.known(&()));
+// match x {
+// Ok(value) => *value += 1,
+// Err(_) => todo!(),
+// }
+// assert_eq!(z, 43);
+// }
+// }
diff --git a/src/symbol.rs b/src/symbol.rs
index e5d984f..1809897 100644
--- a/src/symbol.rs
+++ b/src/symbol.rs
@@ -10,7 +10,7 @@ use range::*;
/// Unique symbol, given a unique tag.
///
/// ```
-/// use uniserde::symbol::Symbol;
+/// use treaty::symbol::Symbol;
///
/// const PROPERTY: Symbol = Symbol::new("Property");
/// # let _ = PROPERTY;
@@ -78,7 +78,7 @@ impl Symbol {
/// This is provided to allow using a [`Symbol`] as a const generic.
///
/// ```
- /// use uniserde::symbol::Symbol;
+ /// use treaty::symbol::Symbol;
///
/// struct MyType<const N: u64>;
///
@@ -210,6 +210,7 @@ fn decode(input: u64, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut offset = 0;
// Read a bit to fill the precision.
+ #[allow(clippy::mut_range_bound)]
for _ in 0..precision {
input_buffer = (input_buffer << 1)
| match bit(&mut precision, &mut offset, input) {
@@ -755,6 +756,7 @@ mod test {
}
#[test]
+ #[allow(clippy::approx_constant)]
fn alphabet() {
// This test is special. It generates the model table from a set
// of basic probability lists. If the table in the code is wrong
@@ -790,7 +792,7 @@ mod test {
('z', 0.07),
]);
assert_eq!(lower.len(), 26);
- assert!((lower.iter().map(|(_, x)| x).sum::<f64>() - 100.0).abs() < 0.1);
+ assert!((lower.values().sum::<f64>() - 100.0).abs() < 0.1);
let upper = HashMap::<char, f64>::from([
('A', 5.64),
@@ -821,7 +823,7 @@ mod test {
('Z', 0.27),
]);
assert_eq!(upper.len(), 26);
- assert!((upper.iter().map(|(_, x)| x).sum::<f64>() - 100.0).abs() < 0.1);
+ assert!((upper.values().sum::<f64>() - 100.0).abs() < 0.1);
let digit = HashMap::<char, f64>::from([
('1', 30.1),
@@ -836,11 +838,11 @@ mod test {
('0', 1.0),
]);
assert_eq!(digit.len(), 10);
- assert!((digit.iter().map(|(_, x)| x).sum::<f64>() - 100.0).abs() < 0.1);
+ assert!((digit.values().sum::<f64>() - 100.0).abs() < 0.1);
let extra = HashMap::<char, f64>::from([(' ', 30.0), ('_', 60.0), ('-', 10.0)]);
assert_eq!(extra.len(), 3);
- assert!((extra.iter().map(|(_, x)| x).sum::<f64>() - 100.0).abs() < 0.1);
+ assert!((extra.values().sum::<f64>() - 100.0).abs() < 0.1);
let all: HashMap<char, f64> = lower
.iter()
@@ -897,6 +899,7 @@ mod test {
// This is the model used in the arithmetic coding.
#[rustfmt::skip]
+#[allow(clippy::items_after_test_module)]
const ALPHABET: &[(u8, [(u64, u64); 18])] = &[
(b' ', [(0,1180),(0,1178),(0,1168),(0,1153),(0,1123),(0,1092),(0,1058),(0,1020),(0,980),(0,935),(0,885),(0,828),(0,763),(0,685),(0,590),(0,468),(0,0),(0,0),]),
(b'-', [(1180,393),(1178,393),(1168,389),(1153,384),(1123,374),(1092,364),(1058,353),(1020,340),(980,327),(935,312),(885,295),(828,276),(763,254),(685,228),(590,197),(468,156),(0,0),(0,0),]),
diff --git a/src/transform.rs b/src/transform.rs
index 9d696be..64aea20 100644
--- a/src/transform.rs
+++ b/src/transform.rs
@@ -5,10 +5,11 @@ use crate::{
};
#[inline]
-pub fn transform<'a, 'ctx, B: Builder<'ctx, E> + 'a, W: Walker<'ctx, E> + 'a, E: Effect<'ctx>>(
+#[allow(clippy::type_complexity)]
+pub fn transform<'a, 'ctx, B: Builder<'ctx, E> + 'a, W: Walker<'ctx, E> + 'a, E: Effect>(
seed: B::Seed,
walker: W,
-) -> Future<'a, 'ctx, (Result<B::Value, B::Error>, Result<W::Output, W::Error>), E> {
+) -> Future<'a, (Result<B::Value, B::Error>, Result<W::Output, W::Error>), E> {
E::wrap(async {
// Create builder from seed value;
let mut builder = B::from_seed(seed).await;
diff --git a/src/walk.rs b/src/walk.rs
index c991377..672bfd3 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -7,7 +7,7 @@ use crate::{
};
/// A type that can be walked.
-pub trait Walk<'ctx, M, E: Effect<'ctx>>: WalkerTypes + Sized {
+pub trait Walk<'ctx, M, E: Effect>: WalkerTypes + Sized {
/// The walker for the type.
type Walker: Walker<'ctx, E, Error = Self::Error, Output = Self::Output>;
@@ -33,20 +33,20 @@ pub trait WalkerTypes {
/// - Call [From::from()] with a value to be walked to make a walker.
/// - Call [Self::walk()] to walk the value. Data will be sent to the provided
/// visitor.
-pub trait Walker<'ctx, E: Effect<'ctx>>: WalkerTypes + Send {
+pub trait Walker<'ctx, E: Effect>: WalkerTypes + Send {
/// Walk the value.
///
/// The walker should send data to the `visitor` as it walks the value.
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
+ ) -> Future<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a;
}
-pub trait WalkerObjSafe<'ctx, E: Effect<'ctx>>: Send {
- fn walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E>
+pub trait WalkerObjSafe<'ctx, E: Effect>: Send {
+ fn walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E>
where
Self: 'a;
}
@@ -102,8 +102,8 @@ impl<W: WalkerTypes> DynWalkerAdapter<W> {
}
}
-impl<'ctx, W: Walker<'ctx, E>, E: Effect<'ctx>> WalkerObjSafe<'ctx, E> for DynWalkerAdapter<W> {
- fn walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E>
+impl<'ctx, W: Walker<'ctx, E>, E: Effect> WalkerObjSafe<'ctx, E> for DynWalkerAdapter<W> {
+ fn walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E>
where
Self: 'a,
{
diff --git a/src/walk/walkers/core/bool.rs b/src/walk/walkers/core/bool.rs
index 5e173fa..03929e5 100644
--- a/src/walk/walkers/core/bool.rs
+++ b/src/walk/walkers/core/bool.rs
@@ -1,8 +1,8 @@
use crate::{effect::Effect, Walk, WalkerTypes};
-use super::value::{BorrowWalker, ValueWalker};
+use super::value::ValueWalker;
-impl<'ctx, M, E: Effect<'ctx>> Walk<'ctx, M, E> for bool {
+impl<'ctx, M, E: Effect> Walk<'ctx, M, E> for bool {
type Walker = ValueWalker<bool>;
fn into_walker(self) -> Self::Walker {
@@ -15,7 +15,7 @@ impl WalkerTypes for bool {
type Output = <ValueWalker<bool> as WalkerTypes>::Output;
}
-impl<'ctx, M, E: Effect<'ctx>> Walk<'ctx, M, E> for &'ctx bool {
+impl<'ctx, M, E: Effect> Walk<'ctx, M, E> for &'ctx bool {
type Walker = ValueWalker<bool>;
fn into_walker(self) -> Self::Walker {
diff --git a/src/walk/walkers/core/key_value.rs b/src/walk/walkers/core/key_value.rs
index 6eb2210..36f2281 100644
--- a/src/walk/walkers/core/key_value.rs
+++ b/src/walk/walkers/core/key_value.rs
@@ -29,6 +29,7 @@ impl<T, K, V> KeyValueWalker<T, K, V> {
}
#[derive(Debug)]
+#[allow(unused)]
enum KeyValueErrorKind<K, V> {
Tag(TagError<Never>),
Key(K),
@@ -50,7 +51,7 @@ where
impl<'ctx, T, K, V, E> crate::Walker<'ctx, E> for KeyValueWalker<T, K, V>
where
- E: Effect<'ctx>,
+ E: Effect,
T: TagKind,
K: crate::Walker<'ctx, E>,
V: crate::Walker<'ctx, E>,
@@ -58,7 +59,7 @@ where
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
+ ) -> Future<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
@@ -73,12 +74,12 @@ where
.await
{
Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => return Ok(()),
+ Ok(Status::Flow(_flow)) => return Ok(()),
Err(_) => todo!(),
}
}
Ok(Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => todo!(),
+ Ok(Status::Flow(_flow)) => todo!(),
Err(_) => todo!(),
}
@@ -90,7 +91,7 @@ where
.await
{
Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {}
- Ok(Status::Flow(flow)) => return Ok(()),
+ Ok(Status::Flow(_flow)) => return Ok(()),
Err(_) => todo!(),
}
@@ -106,10 +107,10 @@ where
// Fallback to just walking the value.
match value_walker.walk(visitor).await {
Ok(_) => {}
- Err(err) => todo!(),
+ Err(_err) => todo!(),
}
}
- Ok(Status::Flow(flow)) => todo!(),
+ Ok(Status::Flow(_flow)) => todo!(),
Err(_) => todo!(),
}
diff --git a/src/walk/walkers/core/noop.rs b/src/walk/walkers/core/noop.rs
index ec7f8ae..8bb05cb 100644
--- a/src/walk/walkers/core/noop.rs
+++ b/src/walk/walkers/core/noop.rs
@@ -9,7 +9,7 @@ use crate::{
///
/// This walker is useful for tags that don't need a value.
#[non_exhaustive]
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub struct NoopWalker;
impl NoopWalker {
@@ -24,11 +24,11 @@ impl WalkerTypes for NoopWalker {
type Output = ();
}
-impl<'ctx, E: Effect<'ctx>> crate::Walker<'ctx, E> for NoopWalker {
+impl<'ctx, E: Effect> crate::Walker<'ctx, E> for NoopWalker {
fn walk<'a>(
self,
_visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
+ ) -> Future<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs
index e78094e..406e703 100644
--- a/src/walk/walkers/core/struct.rs
+++ b/src/walk/walkers/core/struct.rs
@@ -1,24 +1,19 @@
-use core::{any::TypeId, marker::PhantomData};
+use core::any::TypeId;
use crate::{
- any::static_wrapper::{BorrowedStatic, DynBorrowedStatic},
- any_trait,
- effect::{Effect, Future},
- never::Never,
- protocol::{
+ any::static_wrapper::{BorrowedStatic, DynBorrowedStatic}, 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},
+ value::{visit_value, DynValue, ValueKnown},
Status,
},
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, WalkerTypes, TAG_FIELD_NAMES, TAG_MAP, TAG_STRUCT, TAG_TYPE_ID, TAG_TYPE_NAME
};
use super::{noop::NoopWalker, tag::StaticSliceWalker, value::ValueWalker};
@@ -38,7 +33,7 @@ pub struct StructWalker<'ctx, T, I: StructTypeInfo<'ctx, M>, M, E> {
/// The visitor tracks it's own errors.
error: Option<StructWalkErrorKind<I::FieldError>>,
- _marker: PhantomData<fn() -> (I, M, E)>,
+ _generics: Marker<(I, M, E)>,
}
/// Type info about a struct needed by [`StructWalker`].
@@ -56,14 +51,15 @@ pub trait StructTypeInfo<'ctx, M>: 'static {
type T: Send;
/// Walk the given field.
- fn walk_field<'a, E: Effect<'ctx>>(
+ fn walk_field<'a, E: Effect>(
index: usize,
value: &'ctx Self::T,
visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Flow, Self::FieldError>, E>;
+ ) -> Future<'a, Result<Flow, Self::FieldError>, E>;
}
#[derive(Debug)]
+#[allow(unused)]
enum StructWalkErrorKind<T> {
/// Error with visiting a tag for the struct.
///
@@ -81,6 +77,7 @@ enum StructWalkErrorKind<T> {
/// Error from walking a struct.
#[derive(Debug)]
+#[allow(unused)]
pub struct StructWalkError<T> {
kind: StructWalkErrorKind<T>,
}
@@ -95,7 +92,7 @@ where
value,
index: 0,
error: None,
- _marker: PhantomData,
+ _generics: Default::default(),
}
}
}
@@ -110,14 +107,14 @@ where
impl<'ctx, T, I, E, M> crate::Walker<'ctx, E> for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M, T = T>,
T: Sync + 'static,
{
fn walk<'a>(
mut self,
visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
+ ) -> Future<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
@@ -146,14 +143,14 @@ any_trait! {
DynHint<'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E>, E>,
DynHint<'ctx, DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, E>,
] where
- E: Effect<'ctx>,
+ E: Effect,
T: Sync + 'static,
I: StructTypeInfo<'ctx, M, T = T>
}
impl<'ctx, T, I, M, E> Hint<'ctx, DynRecoverable<'ctx, E>, E> for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M, T = T>,
T: Sync + 'static,
{
@@ -161,7 +158,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
_hint: <DynRecoverable<'ctx, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::map(
visit_recoverable::<E>(visitor, self),
|status| match status {
@@ -174,7 +171,7 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <DynRecoverable<'ctx, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynRecoverable<'ctx, E>>, ()>, E> {
+ ) -> Future<'a, Result<Known<'a, 'ctx, DynRecoverable<'ctx, E>>, ()>, E> {
E::ready(Ok(()))
}
}
@@ -182,7 +179,7 @@ where
impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, E>
for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M>,
T: Sync + 'static,
{
@@ -190,7 +187,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
_hint: <DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::map(
visit_tag::<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E, _>(
TagConst,
@@ -213,9 +210,7 @@ where
_hint: &'a <DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E> as HintMeta<
'ctx,
>>::Hint,
- ) -> Future<
- 'a,
- 'ctx,
+ ) -> Future<'a,
Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, ()>,
E,
> {
@@ -228,7 +223,7 @@ where
impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E>, E>
for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M>,
T: Sync + 'static,
{
@@ -236,7 +231,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
_hint: <DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::map(
visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(
TagConst,
@@ -259,7 +254,6 @@ where
_hint: &'a <DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta<'ctx>>::Hint,
) -> Future<
'a,
- 'ctx,
Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, ()>,
E,
> {
@@ -272,7 +266,7 @@ where
impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E>, E>
for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M>,
T: Sync + 'static,
{
@@ -280,7 +274,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
_hint: <DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::map(
visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()),
|status| match status {
@@ -299,7 +293,6 @@ where
_hint: &'a <DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta<'ctx>>::Hint,
) -> Future<
'a,
- 'ctx,
Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_MAP.to_int() }>, E>>, ()>,
E,
> {
@@ -312,7 +305,7 @@ where
impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E>, E>
for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M>,
T: Sync + 'static,
{
@@ -320,7 +313,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
_hint: <DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::map(
visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(
TagConst,
@@ -343,7 +336,6 @@ where
_hint: &'a <DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta<'ctx>>::Hint,
) -> Future<
'a,
- 'ctx,
Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E>>, ()>,
E,
> {
@@ -356,7 +348,7 @@ where
impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E>, E>
for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M>,
T: Sync + 'static,
{
@@ -364,7 +356,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
_hint: <DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::map(
visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>(
TagConst,
@@ -387,7 +379,6 @@ where
_hint: &'a <DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta<'ctx>>::Hint,
) -> Future<
'a,
- 'ctx,
Result<Known<'a, 'ctx, DynTag<'ctx, TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, ()>,
E,
> {
@@ -399,7 +390,7 @@ where
impl<'ctx, T, I, M, E> Hint<'ctx, DynTag<'ctx, TagDyn, E>, E> for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M>,
T: Sync + 'static,
{
@@ -407,7 +398,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
hint: <DynTag<'ctx, TagDyn, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
match hint.kind.0 {
crate::TAG_TYPE_ID => Hint::<
'ctx,
@@ -445,7 +436,7 @@ where
fn known<'a>(
&'a mut self,
hint: &'a <DynTag<'ctx, TagDyn, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynTag<'ctx, TagDyn, E>>, ()>, E> {
+ ) -> Future<'a, Result<Known<'a, 'ctx, DynTag<'ctx, TagDyn, E>>, ()>, E> {
E::ready(match hint.kind {
TagDyn(crate::TAG_TYPE_ID) | TagDyn(crate::TAG_STRUCT) => Ok(TagKnown {
kind_available: Some(true),
@@ -460,11 +451,11 @@ where
impl<'ctx, T, I, M, E> Hint<'ctx, DynValue<'ctx, DynBorrowedStatic<'ctx, T>, E>, E>
for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M>,
T: Sync + 'static,
{
- fn hint<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>, _hint: ()) -> Future<'a, 'ctx, Flow, E> {
+ fn hint<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>, _hint: ()) -> Future<'a, Flow, E> {
E::map(
visit_value::<_, E>(visitor, BorrowedStatic(self.value)),
|status| match status {
@@ -474,14 +465,14 @@ where
)
}
- fn known<'a>(&'a mut self, _hint: &'a ()) -> Future<'a, 'ctx, Result<(), ()>, E> {
- E::ready(Ok(()))
+ fn known<'a>(&'a mut self, _hint: &'a ()) -> Future<'a, Result<ValueKnown, ()>, E> {
+ E::ready(Ok(ValueKnown))
}
}
impl<'ctx, T, I, M, E> Hint<'ctx, DynSequence<'ctx, E>, E> for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M, T = T>,
T: Sync,
{
@@ -489,7 +480,7 @@ where
&'a mut self,
visitor: Visitor<'a, 'ctx>,
_hint: <DynSequence<'ctx, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Flow, E> {
+ ) -> Future<'a, Flow, E> {
E::map(visit_sequence::<E>(visitor, self), |status| match status {
Status::Skipped(_) => Flow::Continue,
Status::Flow(flow) => flow,
@@ -499,7 +490,7 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <DynSequence<'ctx, E> as HintMeta<'ctx>>::Hint,
- ) -> Future<'a, 'ctx, Result<Known<'a, 'ctx, DynSequence<'ctx, E>>, ()>, E> {
+ ) -> Future<'a, Result<Known<'a, 'ctx, DynSequence<'ctx, E>>, ()>, E> {
let len = I::FIELDS.len();
E::ready(Ok(SequenceKnown {
@@ -510,16 +501,16 @@ where
impl<'ctx, T, I, M, E> SequenceScope<'ctx, E> for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M, T = T>,
{
- fn size_hint<'a>(&'a mut self) -> Future<'a, 'ctx, (usize, Option<usize>), E> {
+ fn size_hint(&mut self) -> Future<'_, (usize, Option<usize>), E> {
let len = I::FIELDS.len();
E::ready((len, Some(len)))
}
- fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E> {
+ fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E> {
if self.index >= I::FIELDS.len() {
return E::ready(Flow::Done);
}
@@ -543,11 +534,11 @@ where
impl<'ctx, T, I, M, E> RecoverableScope<'ctx, E> for StructWalker<'ctx, T, I, M, E>
where
- E: Effect<'ctx>,
+ E: Effect,
I: StructTypeInfo<'ctx, M, T = T>,
T: Sync + 'static,
{
- fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E> {
+ fn new_walk<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E> {
// Reset the errors to default state.
self.error = None;
@@ -659,152 +650,3 @@ where
})
}
}
-
-#[cfg(test)]
-mod test {
- use mockall::{predicate::eq, Sequence};
-
- use crate::{
- any::{
- static_wrapper::{DynOwnedStatic, OwnedStatic},
- TypeNameId,
- },
- effect::{BlockOn as _, Blocking, Spin},
- mock::{
- builder::MockBuilder,
- protocol::{tag::MockTagVisitor, value::MockValueVisitor},
- },
- symbol::Symbol,
- Builder, DefaultMode, Walker,
- };
-
- use super::*;
-
- struct Demo {
- a: bool,
- b: bool,
- }
-
- impl<'ctx, M> StructTypeInfo<'ctx, M> for Demo {
- const NAME: &'static str = "Demo";
-
- const FIELDS: &'static [&'static str] = &["a", "b"];
-
- type FieldError = ();
-
- type T = Demo;
-
- fn walk_field<'a, E: Effect<'ctx>>(
- index: usize,
- value: &'ctx Self::T,
- visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Flow, Self::FieldError>, E> {
- E::wrap(async move {
- match index {
- 0 => {
- let walker = ValueWalker::<bool>::new(value.a);
- Walker::<E>::walk(walker, visitor).await.unwrap();
- Ok(Flow::Continue)
- }
- 1 => {
- let walker = ValueWalker::<bool>::new(value.b);
- Walker::<E>::walk(walker, visitor).await.unwrap();
- Ok(Flow::Continue)
- }
- _ => Ok(Flow::Done),
- }
- })
- }
- }
-
- #[test]
- fn demo2() {
- let mut builder = MockBuilder::<(), (), ()>::new();
-
- let mut seq = Sequence::new();
-
- builder
- .expect_traits_mut()
- .times(4)
- .in_sequence(&mut seq)
- .return_var(None);
-
- builder
- .expect_traits_mut()
- .once()
- .with(eq(TypeNameId::of::<
- DynTag<'static, TagConst<{ TAG_STRUCT.to_int() }>, Blocking>,
- >()))
- .in_sequence(&mut seq)
- .return_var(Some(Box::new({
- let mut mock = MockTagVisitor::<TagConst<{ TAG_STRUCT.to_int() }>, Blocking>::new();
-
- mock.expect_visit().once().returning(|_, walker| {
- let mut builder = MockBuilder::<(), (), ()>::new();
- assert_eq!(
- Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))),
- Flow::Done
- );
-
- Flow::Continue
- });
-
- mock
- })));
-
- builder
- .expect_traits_mut()
- .once()
- .with(eq(TypeNameId::of::<
- DynTag<'static, TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>,
- >()))
- .in_sequence(&mut seq)
- .return_var(Some(Box::new({
- let mut mock =
- MockTagVisitor::<TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>::new();
-
- mock.expect_visit().return_once(|_, walker| {
- let mut builder = MockBuilder::<(), (), ()>::new();
-
- builder
- .expect_traits_mut()
- .once()
- .with(eq(TypeNameId::of::<
- DynValue<'static, DynOwnedStatic<&'static str>, Blocking>,
- >()))
- .return_var(Some(Box::new({
- let mut mock =
- MockValueVisitor::<DynOwnedStatic<&'static str>, Blocking>::new();
-
- mock.expect_visit()
- .once()
- .with(eq(OwnedStatic("Demo")))
- .return_const(Flow::Done);
-
- mock
- })));
-
- assert_eq!(
- Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))),
- Flow::Done
- );
-
- Flow::Continue
- });
-
- mock
- })));
-
- builder
- .expect_traits_mut()
- .times(3)
- .in_sequence(&mut seq)
- .return_var(None);
-
- let value = Demo { a: true, b: false };
-
- let walker = StructWalker::<Demo, Demo, DefaultMode, Blocking>::new(&value);
-
- Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))).unwrap();
- }
-}
diff --git a/src/walk/walkers/core/tag.rs b/src/walk/walkers/core/tag.rs
index 22e117b..0deab96 100644
--- a/src/walk/walkers/core/tag.rs
+++ b/src/walk/walkers/core/tag.rs
@@ -1,25 +1,23 @@
-use core::{any::TypeId, marker::PhantomData};
+use core::marker::PhantomData;
use crate::{
- any::static_wrapper::{DynOwnedStatic, OwnedStatic},
+ any::static_wrapper::OwnedStatic,
any_trait,
effect::{Effect, Future},
never::Never,
protocol::{
visitor::{
- request_hint::{visit_request_hint, DynRequestHint, RequestHint},
+ request_hint::visit_request_hint,
sequence::{DynSequence, SequenceScope},
- tag::{DynTag, TagError},
- value::{visit_value, DynValue, Value},
+ tag::TagError,
+ value::visit_value,
Status,
},
Visitor,
},
- Flow, WalkerTypes, TAG_FIELD_NAMES, TAG_SEQ_INDEX, TAG_SEQ_LEN,
+ Flow, WalkerTypes
};
-use super::value::ValueWalker;
-
pub struct StaticSliceWalker<T: 'static, W> {
names: &'static [T],
current: usize,
@@ -44,7 +42,7 @@ impl<T, W> WalkerTypes for StaticSliceWalker<T, W> {
impl<'ctx, T, W, E> crate::Walker<'ctx, E> for StaticSliceWalker<T, W>
where
- E: Effect<'ctx>,
+ E: Effect,
W: crate::Walker<'ctx, E> + WalkerTypes<Output = ()>,
T: Sync,
&'static T: Into<W>,
@@ -52,7 +50,7 @@ where
fn walk<'a>(
mut self,
visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
+ ) -> Future<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
@@ -85,12 +83,12 @@ any_trait! {
impl<'ctx, T, W, E> SequenceScope<'ctx, E> for StaticSliceWalker<T, W>
where
- E: Effect<'ctx>,
+ E: Effect,
W: crate::Walker<'ctx, E> + WalkerTypes<Output = ()>,
T: Sync,
&'static T: Into<W>,
{
- fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, 'ctx, Flow, E> {
+ fn next<'a>(&'a mut self, visitor: Visitor<'a, 'ctx>) -> Future<'a, Flow, E> {
if let Some(name) = self.names.get(self.current) {
self.current += 1;
E::wrap(async move {
@@ -104,7 +102,7 @@ where
}
}
- fn size_hint<'a>(&'a mut self) -> Future<'a, 'ctx, (usize, Option<usize>), E> {
+ fn size_hint(&mut self) -> Future<'_, (usize, Option<usize>), E> {
E::ready((self.names.len(), Some(self.names.len())))
}
}
diff --git a/src/walk/walkers/core/value.rs b/src/walk/walkers/core/value.rs
index 64586ca..d5b35b9 100644
--- a/src/walk/walkers/core/value.rs
+++ b/src/walk/walkers/core/value.rs
@@ -38,11 +38,11 @@ impl<T> WalkerTypes for ValueWalker<T> {
type Output = ();
}
-impl<'ctx, T: Send + 'static, E: Effect<'ctx>> crate::Walker<'ctx, E> for ValueWalker<T> {
+impl<'ctx, T: Send + 'static, E: Effect> crate::Walker<'ctx, E> for ValueWalker<T> {
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
+ ) -> Future<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
@@ -72,13 +72,13 @@ impl<'ctx, T: ?Sized> WalkerTypes for BorrowWalker<'ctx, T> {
type Output = ();
}
-impl<'ctx, T: ?Sized + Sync + 'static, E: Effect<'ctx>> crate::Walker<'ctx, E>
+impl<'ctx, T: ?Sized + Sync + 'static, E: Effect> crate::Walker<'ctx, E>
for BorrowWalker<'ctx, T>
{
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
+ ) -> Future<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
diff --git a/tests/async.rs b/tests/async.rs
deleted file mode 100644
index 13968ab..0000000
--- a/tests/async.rs
+++ /dev/null
@@ -1,148 +0,0 @@
-use std::{collections::VecDeque, future::Future, ops::ControlFlow, pin::Pin};
-use treaty::{
- any::{any_trait, static_wrapper::OwnedStatic},
- async_build_with, build_with, into_walker,
- protocol::{
- visitor::{Sequence, SequenceScope, Status, Value},
- AsyncEffect, ControlFlowFor, Visitor,
- },
- Builder, Walk, Walker,
-};
-
-#[tokio::test]
-async fn demo() {
- let a = Data::Sequence(vec![
- Data::Bool(true),
- Data::Sequence(vec![Data::Bool(false), Data::Bool(true)]),
- Data::Bool(false),
- ]);
-
- let s = async_build_with::<JsonLike, _>(into_walker(a))
- .await
- .unwrap();
-
- assert_eq!(s, "[true,[false,true,],false,]");
-}
-
-#[derive(Debug)]
-enum Data {
- Bool(bool),
- Sequence(Vec<Data>),
-}
-
-const _: () = {
- struct Impl(Data);
-
- impl From<Data> for Impl {
- fn from(value: Data) -> Self {
- Self(value)
- }
- }
-
- impl<'ctx> Walk<'ctx> for Data {
- type Walker = Impl;
- }
-
- impl<'ctx> Walker<'ctx> for Impl {
- type Effect = AsyncEffect;
-
- type Error = ();
-
- type Output = ();
-
- fn walk<'a>(self, visitor: &'a mut Visitor<'a, 'ctx>) -> ControlFlowFor<'a, AsyncEffect> {
- Box::pin(async {
- match self.0 {
- Data::Bool(value) => walk_bool(value, visitor),
- Data::Sequence(value) => walk_vec(value, visitor).await,
- }
- core::ops::ControlFlow::Continue(())
- })
- }
- }
-};
-
-fn walk_bool(value: bool, visitor: &mut Visitor<'_, '_>) {
- visitor
- .upcast_mut::<dyn Value<OwnedStatic<bool>>>()
- .unwrap()
- .visit(OwnedStatic(value));
-}
-
-async fn walk_vec(value: Vec<Data>, visitor: &mut Visitor<'_, '_>) {
- struct Scope(VecDeque<Data>);
-
- impl<'ctx> SequenceScope<'ctx, AsyncEffect> for Scope {
- fn next<'a>(
- &'a mut self,
- visitor: &'a mut Visitor<'a, 'ctx>,
- ) -> ControlFlowFor<'a, AsyncEffect, Status> {
- Box::pin(async {
- if let Some(value) = self.0.pop_front() {
- into_walker(value).walk(visitor).await;
-
- ControlFlow::Continue(Status::Continue)
- } else {
- ControlFlow::Continue(Status::Done)
- }
- })
- }
- }
-
- let mut scope = Scope(value.into());
-
- visitor
- .upcast_mut::<dyn Sequence<'_, AsyncEffect>>()
- .unwrap()
- .visit(&mut scope)
- .await;
-}
-
-#[derive(Default)]
-struct JsonLike(String);
-
-impl<'ctx> Builder<'ctx> for JsonLike {
- type Error = ();
-
- type Value = String;
-
- fn as_visitor(&mut self) -> &mut Visitor<'_, 'ctx> {
- self
- }
-
- fn build(self) -> Result<Self::Value, Self::Error> {
- Ok(self.0)
- }
-}
-
-any_trait! {
- impl['a, 'ctx] JsonLike = [
- dyn Value<'a, OwnedStatic<bool>> + 'a,
- dyn Sequence<'ctx, AsyncEffect> + 'a,
- ];
-}
-
-impl Value<'_, OwnedStatic<bool>> for JsonLike {
- fn visit(&mut self, value: OwnedStatic<bool>) -> core::ops::ControlFlow<()> {
- self.0.push_str(&format!("{}", value.0));
- std::ops::ControlFlow::Continue(())
- }
-}
-
-impl<'ctx> Sequence<'ctx, AsyncEffect> for JsonLike {
- fn visit<'a>(
- &'a mut self,
- scope: &'a mut dyn SequenceScope<'ctx, AsyncEffect>,
- ) -> ControlFlowFor<'a, AsyncEffect> {
- Box::pin(async {
- self.0.push_str("[");
- while let std::ops::ControlFlow::Continue(treaty::protocol::visitor::Status::Continue) =
- scope.next(self).await
- {
- self.0.push_str(",");
- }
- self.0.push_str("]");
- std::ops::ControlFlow::Continue(())
- })
- }
-}
diff --git a/src/mock/builder.rs b/tests/common/builder.rs
index 9fef358..d2b182f 100644
--- a/src/mock/builder.rs
+++ b/tests/common/builder.rs
@@ -1,12 +1,7 @@
use mockall::mock;
+use treaty::{any::{indirect, AnyTrait, AnyTraitObject, TypeNameId}, effect::{Effect, Future}, protocol::Visitor, Builder, BuilderTypes};
-use crate::{
- any::{indirect, AnyTrait, AnyTraitObject, TypeNameId},
- effect::{Effect, Future},
- mock::{ContextLock, StaticTypeMap},
- protocol::Visitor,
- Builder, BuilderTypes,
-};
+use crate::common::{ContextLock, StaticTypeMap};
use self::__mock_MockBuilder::__from_seed::Context;
@@ -44,33 +39,29 @@ impl<Seed: 'static, Value: 'static, Error: 'static> MockBuilder<Seed, Value, Err
}
}
-impl<'ctx, Seed: Send, Value: Send, Error: Send, E: Effect<'ctx>> Builder<'ctx, E>
+impl<'ctx, Seed: Send, Value: Send, Error: Send, E: Effect> Builder<'ctx, E>
for MockBuilder<Seed, Value, Error>
{
- #[track_caller]
- fn from_seed<'a>(seed: Self::Seed) -> Future<'a, 'ctx, Self, E>
+ fn from_seed<'a>(seed: Self::Seed) -> Future<'a, Self, E>
where
Self: 'a,
{
E::ready(Self::from_seed(seed))
}
- #[track_caller]
- fn build<'a>(self) -> Future<'a, 'ctx, Result<Self::Value, Self::Error>, E>
+ fn build<'a>(self) -> Future<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a,
{
E::ready(self.build())
}
- #[track_caller]
fn as_visitor(&mut self) -> Visitor<'_, 'ctx> {
self
}
}
impl<'ctx, Seed, Value, Error> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error> {
- #[track_caller]
fn upcast_to_id<'a>(&'a self, id: TypeNameId) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref>>
where
'ctx: 'a,
@@ -79,7 +70,6 @@ impl<'ctx, Seed, Value, Error> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error
self.traits(id).as_ref().and_then(|t| t.upcast_to_id(id))
}
- #[track_caller]
fn upcast_to_id_mut<'a>(
&'a mut self,
id: TypeNameId,
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
new file mode 100644
index 0000000..8b9fb03
--- /dev/null
+++ b/tests/common/mod.rs
@@ -0,0 +1,83 @@
+#![allow(unused)]
+
+use core::{
+ any::{Any, TypeId},
+ ops::Deref,
+};
+use std::{
+ collections::HashMap,
+ sync::{Mutex, MutexGuard, OnceLock, RwLock},
+};
+
+pub mod builder;
+pub mod protocol;
+
+pub struct StaticTypeMap {
+ map: OnceLock<RwLock<HashMap<TypeId, &'static (dyn Any + Send + Sync)>>>,
+}
+
+impl StaticTypeMap {
+ pub const fn new() -> Self {
+ Self {
+ map: OnceLock::new(),
+ }
+ }
+
+ pub fn get_or_init<T: Send + Sync + 'static, F: FnOnce() -> T>(&self, f: F) -> &'static T {
+ let map_init = || RwLock::new(HashMap::new());
+
+ let map = self.map.get_or_init(map_init).read().unwrap();
+
+ if let Some(once) = map.get(&TypeId::of::<T>()) {
+ return once.downcast_ref::<T>().unwrap();
+ }
+
+ drop(map);
+
+ let mut map = self.map.get_or_init(map_init).write().unwrap();
+ let once = &*Box::leak(Box::new(f()));
+ map.insert(TypeId::of::<T>(), once);
+
+ once
+ }
+}
+
+pub struct ContextLock<T> {
+ lock: Mutex<T>,
+ checkpoint: fn(&T),
+}
+
+impl<T> ContextLock<T> {
+ pub const fn new(context: T, checkpoint: fn(&T)) -> Self {
+ Self {
+ lock: Mutex::new(context),
+ checkpoint,
+ }
+ }
+
+ pub fn lock(&self) -> ContextGuard<'_, T> {
+ ContextGuard {
+ lock: self,
+ guard: self.lock.lock().unwrap(),
+ }
+ }
+}
+
+pub struct ContextGuard<'a, T> {
+ lock: &'a ContextLock<T>,
+ guard: MutexGuard<'a, T>,
+}
+
+impl<'a, T> Drop for ContextGuard<'a, T> {
+ fn drop(&mut self) {
+ (self.lock.checkpoint)(&*self.guard)
+ }
+}
+
+impl<'a, T> Deref for ContextGuard<'a, T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.guard
+ }
+}
diff --git a/tests/common/protocol.rs b/tests/common/protocol.rs
new file mode 100644
index 0000000..e33df66
--- /dev/null
+++ b/tests/common/protocol.rs
@@ -0,0 +1,2 @@
+pub mod visitor;
+pub mod tag;
diff --git a/src/mock/protocol/tag.rs b/tests/common/protocol/tag.rs
index e1c9551..23916d1 100644
--- a/src/mock/protocol/tag.rs
+++ b/tests/common/protocol/tag.rs
@@ -1,11 +1,5 @@
use mockall::mock;
-
-use crate::{
- any_trait,
- effect::{Effect, Future},
- protocol::visitor::tag::{DynTag, Tag, TagKind},
- DynWalker,
-};
+use treaty::{any::any_trait, effect::{Effect, Future}, protocol::visitor::tag::{DynTag, Tag, TagKind}, DynWalker};
mock! {
pub TagVisitor<K: TagKind, E> {
@@ -18,16 +12,15 @@ any_trait! {
DynTag<'ctx, K, E>,
] where
K: TagKind,
- E: Effect<'ctx>,
+ E: Effect,
}
-impl<'ctx, K: TagKind, E: Effect<'ctx>> Tag<'ctx, K, E> for MockTagVisitor<K, E> {
- #[track_caller]
+impl<'ctx, K: TagKind, E: Effect> Tag<'ctx, K, E> for MockTagVisitor<K, E> {
fn visit<'a>(
&'a mut self,
kind: K,
walker: DynWalker<'a, 'ctx, E>,
- ) -> Future<'a, 'ctx, <K as TagKind>::Flow, E> {
+ ) -> Future<'a, <K as TagKind>::Flow, E> {
E::ready(self.visit(kind, walker))
}
}
diff --git a/src/mock/protocol/value.rs b/tests/common/protocol/visitor.rs
index eca11ee..a71e9ec 100644
--- a/src/mock/protocol/value.rs
+++ b/tests/common/protocol/visitor.rs
@@ -1,12 +1,5 @@
use mockall::mock;
-
-use crate::{
- any::{TypeName, WithContextLt},
- any_trait,
- effect::{Effect, Future},
- protocol::visitor::value::{DynValue, Value},
- Flow,
-};
+use treaty::{any::{any_trait, TypeName, WithContextLt}, effect::{Effect, Future}, protocol::visitor::value::{DynValue, Value}, Flow};
mock! {
pub ValueVisitor<T: for<'ctx> WithContextLt::MemberType<'ctx>, E>
@@ -23,16 +16,16 @@ any_trait! {
] where
T: for<'lt> TypeName::LowerType<'lt> + 'ctx,
for<'a, 'lt> WithContextLt::T<'a, 'lt, T>: Sized,
- E: Effect<'ctx>,
+ E: Effect,
}
-impl<'ctx, T: for<'lt> WithContextLt::MemberType<'lt>, E: Effect<'ctx>> Value<'ctx, T, E>
+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,
{
- #[track_caller]
- fn visit<'a>(&'a mut self, value: WithContextLt::T<'a, 'ctx, T>) -> Future<'a, 'ctx, Flow, E> {
+ fn visit<'a>(&'a mut self, value: WithContextLt::T<'a, 'ctx, T>) -> Future<'a, Flow, E>
+ where 'ctx: 'a {
E::ready(self.visit(value))
}
}
diff --git a/tests/demo.rs b/tests/demo.rs
deleted file mode 100644
index b6bf557..0000000
--- a/tests/demo.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-use std::{collections::VecDeque, ops::ControlFlow};
-use treaty::{
- any::{any_trait, static_wrapper::OwnedStatic},
- build, build_with,
- builders::core::array,
- effect::{SyncEffect, Yield},
- into_walker,
- protocol::{
- visitor::{Sequence, SequenceScope, Value},
- Visitor,
- },
- AsVisitor, Builder, Walk, Walker,
-};
-
-#[test]
-fn demo() {
- let a = Data::Sequence(vec![
- Data::Bool(true),
- Data::Sequence(vec![Data::Bool(false), Data::Bool(true)]),
- Data::Bool(false),
- ]);
-
- dbg!(array_to_array2([true, false]));
- dbg!(array_to_array([true, true]));
-
- let s = build_with::<array::Builder<'_, JsonLike, 3, _>, _>(into_walker(&a)).unwrap();
- dbg!(s);
-
- use treaty::builders::serde::deserialize::Builder as SerdeBuilder;
-
- let x = build_with::<SerdeBuilder<serde_json::Value, _>, _>(into_walker(&a)).unwrap();
- dbg!(x);
-
- // let s = build_with::<JsonLike, _>(into_walker(a)).unwrap();
-
- todo!();
- // assert_eq!(s, "[true,[false,true,],false,]");
-}
-
-#[inline(never)]
-pub fn array_to_array(x: [bool; 2]) -> [bool; 2] {
- build(into_walker(x)).unwrap()
-}
-
-#[inline(never)]
-pub fn array_to_array2(x: [bool; 2]) -> [bool; 2] {
- array_to_array(x)
-}
-
-#[derive(Debug)]
-enum Data {
- Bool(bool),
- Sequence(Vec<Data>),
-}
-
-const _: () = {
- struct Impl<'ctx>(&'ctx Data);
-
- impl<'ctx> From<&'ctx Data> for Impl<'ctx> {
- fn from(value: &'ctx Data) -> Self {
- Self(value)
- }
- }
-
- impl<'ctx> Walk<'ctx> for &'ctx Data {
- type Walker = Impl<'ctx>;
- }
-
- impl<'ctx> Walker<'ctx> for Impl<'ctx> {
- type Effect = SyncEffect;
-
- type Error = ();
-
- type Output = ();
-
- fn walk<'a>(
- self,
- visitor: Visitor<'a, 'ctx, SyncEffect>,
- ) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, SyncEffect>
- where
- 'ctx: 'a,
- {
- match self.0 {
- Data::Bool(value) => walk_bool(*value, visitor),
- Data::Sequence(value) => walk_vec(value, visitor),
- }
- Ok(())
- }
- }
-};
-
-fn walk_bool(value: bool, visitor: Visitor<'_, '_, SyncEffect>) {
- visitor
- .upcast_mut::<dyn Value<OwnedStatic<bool>, SyncEffect>>()
- .unwrap()
- .visit(OwnedStatic(value));
-}
-
-fn walk_vec<'a, 'ctx>(value: &'ctx [Data], visitor: Visitor<'a, 'ctx, SyncEffect>) {
- struct Scope<'ctx>(VecDeque<&'ctx Data>);
-
- impl<'ctx> SequenceScope<'ctx, SyncEffect> for Scope<'ctx> {
- fn next<'a>(
- &'a mut self,
- visitor: Visitor<'a, 'ctx, SyncEffect>,
- ) -> Yield<'a, 'ctx, ControlFlow<(), treaty::protocol::visitor::Status>, SyncEffect>
- where
- 'ctx: 'a,
- {
- if let Some(value) = self.0.pop_front() {
- into_walker(value).walk(visitor);
-
- ControlFlow::Continue(treaty::protocol::visitor::Status::Continue)
- } else {
- ControlFlow::Continue(treaty::protocol::visitor::Status::Done)
- }
- }
- }
-
- let mut scope = Scope(value.into_iter().collect());
-
- visitor
- .upcast_mut::<dyn Sequence<'_, SyncEffect>>()
- .unwrap()
- .visit(&mut scope);
-}
-
-#[derive(Default)]
-struct JsonLike(String);
-
-impl<'ctx> Builder<'ctx, SyncEffect> for JsonLike {
- type Error = ();
-
- type Value = String;
-
- fn build<'a>(self) -> Result<Self::Value, Self::Error>
- where
- Self: 'a,
- {
- Ok(self.0)
- }
-
- type Seed = ();
-
- fn from_seed(seed: Self::Seed) -> Self {
- Self::default()
- }
-
- type Effect = SyncEffect;
-}
-
-impl<'ctx> AsVisitor<'ctx, SyncEffect> for JsonLike {
- fn as_visitor(&mut self) -> Visitor<'_, 'ctx, SyncEffect> {
- self
- }
-}
-
-any_trait! {
- impl['a, 'ctx] JsonLike = [
- dyn Value<'a, 'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
- dyn Sequence<'ctx, SyncEffect> + '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(())
- }
-}
-
-impl<'ctx> Sequence<'ctx, SyncEffect> for JsonLike {
- fn visit<'a>(
- &'a mut self,
- scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>,
- ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
- where
- 'ctx: 'a,
- {
- self.0.push_str("[");
- while let ControlFlow::Continue(treaty::protocol::visitor::Status::Continue) =
- scope.next(self)
- {
- self.0.push_str(",");
- }
- self.0.push_str("]");
- ControlFlow::Continue(())
- }
-}
diff --git a/tests/demo2.rs b/tests/demo2.rs
deleted file mode 100644
index 4bb811a..0000000
--- a/tests/demo2.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use macro_rules_attribute::derive;
-use uniserde::Build;
-
-#[derive(Build!)]
-struct A {
- b: B,
- c: B,
-}
-
-#[derive(Build!)]
-struct B {}
-
-#[test]
-fn demo() {}
diff --git a/tests/hook.rs b/tests/hook.rs
deleted file mode 100644
index 1cb633a..0000000
--- a/tests/hook.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-use std::{marker::PhantomData, ops::ControlFlow, pin::Pin, thread::yield_now, time::Duration};
-
-use treaty::{
- any::{any_trait, static_wrapper::OwnedStatic, AnyTrait, IndirectLtAny, LtTypeId},
- builders::core::option::IgnoreMissing,
- effect::{BlockOn, Blocking, Effect, Future, Spin},
- protocol::visitor::value::Value,
- protocol::Visitor,
- transform, Build, Builder, Walk, Walker, WalkerTypes,
-};
-
-#[test]
-fn demo() {
- let hook = Hook::<_, Blocking> {
- inner: true.into_walker::<Blocking>(),
- _marker: PhantomData,
- };
- // let x = build_with::<<bool as Build<_>>::Builder, _>(hook).unwrap();
- // dbg!(x);
- // let x = Spin::block_on(transform::<<Option<bool> as Build>::Builder<_>, _, Blocking>(IgnoreMissing::No, hook));
- let x = Spin::block_on(transform::<<bool as Build>::Builder<_>, _, Blocking>(
- (),
- hook,
- ));
- dbg!(x);
- todo!();
-}
-
-#[no_mangle]
-fn invert(x: bool) -> bool {
- let hook = Hook::<_, Blocking> {
- inner: x.into_walker::<Blocking>(),
- _marker: PhantomData,
- };
- Spin::block_on(transform::<<bool as Build>::Builder<_>, _, Blocking>(
- (),
- hook,
- ))
- .0
- .unwrap()
-}
-
-struct Hook<T, E> {
- inner: T,
- _marker: PhantomData<fn() -> E>,
-}
-
-struct VisitorHook<'a, 'ctx: 'a, E> {
- inner: Visitor<'a, 'ctx>,
- _marker: PhantomData<fn() -> E>,
-}
-
-impl<'ctx, T: Walker<'ctx, Effect = E>, E: Effect<'ctx>> WalkerTypes<'ctx> for Hook<T, E> {
- type Error = T::Error;
-
- type Output = T::Output;
-}
-
-impl<'ctx, T: Walker<'ctx, Effect = E>, E: Effect<'ctx>> Walker<'ctx> for Hook<T, E> {
- type Effect = E;
-
- fn walk<'a>(
- self,
- visitor: Visitor<'a, 'ctx>,
- ) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
- where
- Self: 'a,
- {
- E::wrap(async {
- let mut visitor = VisitorHook::<E> {
- inner: visitor,
- _marker: PhantomData,
- };
-
- let flow = self.inner.walk(&mut visitor);
-
- flow.await
- })
- }
-}
-
-impl<'b, 'ctx: 'b, E: Effect<'ctx>> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> {
- fn upcast_to_id<'a>(
- &'a self,
- id: treaty::any::LtTypeId<'ctx>,
- ) -> Option<treaty::any::IndirectLtAny<'a, 'ctx, treaty::any::Ref>>
- where
- 'ctx: 'a,
- {
- match id {
- id => self.inner.upcast_to_id(id),
- }
- }
-
- #[inline]
- fn upcast_to_id_mut<'a>(
- &'a mut self,
- id: treaty::any::LtTypeId<'ctx>,
- ) -> Option<treaty::any::IndirectLtAny<'a, 'ctx, treaty::any::Mut>>
- where
- 'ctx: 'a,
- {
- match id {
- id if id == LtTypeId::of::<dyn Value<'a, 'ctx, OwnedStatic<bool>, E> + 'a>() => {
- // println!("hook: {:?}", id);
- if self.inner.upcast_to_id_mut(id).is_some() {
- Some(IndirectLtAny::<'a, 'ctx, _>::new::<
- dyn Value<'a, 'ctx, OwnedStatic<bool>, E> + 'a,
- >(self as _))
- } else {
- None
- }
- }
- id => {
- // println!("fallback: {:?}", id);
- self.inner.upcast_to_id_mut(id)
- }
- }
- }
-}
-
-impl<'a, 'b, 'ctx: 'a + 'b, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<bool>, E>
- for VisitorHook<'b, 'ctx, E>
-{
- #[inline]
- fn visit(
- &'a mut self,
- OwnedStatic(value): OwnedStatic<bool>,
- ) -> Future<'a, 'ctx, ControlFlow<(), ()>, E> {
- let visitor = self
- .inner
- .upcast_mut::<dyn Value<'a, 'ctx, OwnedStatic<bool>, E> + 'a>()
- .unwrap();
-
- // println!("Hooked bool: {}", value);
- visitor.visit(OwnedStatic(!value))
- }
-}
diff --git a/tests/walk.rs b/tests/walk.rs
new file mode 100644
index 0000000..f83ef24
--- /dev/null
+++ b/tests/walk.rs
@@ -0,0 +1,3 @@
+mod common;
+
+mod walkers;
diff --git a/tests/walkers/core.rs b/tests/walkers/core.rs
new file mode 100644
index 0000000..c10aef3
--- /dev/null
+++ b/tests/walkers/core.rs
@@ -0,0 +1 @@
+mod r#struct;
diff --git a/tests/walkers/core/struct.rs b/tests/walkers/core/struct.rs
new file mode 100644
index 0000000..9ea8c31
--- /dev/null
+++ b/tests/walkers/core/struct.rs
@@ -0,0 +1,132 @@
+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}};
+
+struct Demo {
+ a: bool,
+ b: bool,
+}
+
+impl<'ctx, M> StructTypeInfo<'ctx, M> for Demo {
+ const NAME: &'static str = "Demo";
+
+ const FIELDS: &'static [&'static str] = &["a", "b"];
+
+ type FieldError = ();
+
+ type T = Demo;
+
+ fn walk_field<'a, E: Effect>(
+ index: usize,
+ value: &'ctx Self::T,
+ visitor: Visitor<'a, 'ctx>,
+ ) -> Future<'a, Result<Flow, Self::FieldError>, E> {
+ E::wrap(async move {
+ match index {
+ 0 => {
+ let walker = ValueWalker::<bool>::new(value.a);
+ Walker::<E>::walk(walker, visitor).await.unwrap();
+ Ok(Flow::Continue)
+ }
+ 1 => {
+ let walker = ValueWalker::<bool>::new(value.b);
+ Walker::<E>::walk(walker, visitor).await.unwrap();
+ Ok(Flow::Continue)
+ }
+ _ => Ok(Flow::Done),
+ }
+ })
+ }
+}
+
+#[test]
+fn demo2() {
+ let mut builder = MockBuilder::<(), (), ()>::new();
+
+ let mut seq = Sequence::new();
+
+ builder
+ .expect_traits_mut()
+ .times(4)
+ .in_sequence(&mut seq)
+ .return_var(None);
+
+ builder
+ .expect_traits_mut()
+ .once()
+ .with(eq(TypeNameId::of::<
+ DynTag<'static, TagConst<{ TAG_STRUCT.to_int() }>, Blocking>,
+ >()))
+ .in_sequence(&mut seq)
+ .return_var(Some(Box::new({
+ let mut mock = MockTagVisitor::<TagConst<{ TAG_STRUCT.to_int() }>, Blocking>::new();
+
+ mock.expect_visit().once().returning(|_, walker| {
+ let mut builder = MockBuilder::<(), (), ()>::new();
+ assert_eq!(
+ Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))),
+ Flow::Done
+ );
+
+ Flow::Continue
+ });
+
+ mock
+ })));
+
+ builder
+ .expect_traits_mut()
+ .once()
+ .with(eq(TypeNameId::of::<
+ DynTag<'static, TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>,
+ >()))
+ .in_sequence(&mut seq)
+ .return_var(Some(Box::new({
+ let mut mock =
+ MockTagVisitor::<TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>::new();
+
+ mock.expect_visit().return_once(|_, walker| {
+ let mut builder = MockBuilder::<(), (), ()>::new();
+
+ builder
+ .expect_traits_mut()
+ .once()
+ .with(eq(TypeNameId::of::<
+ DynValue<'static, DynOwnedStatic<&'static str>, Blocking>,
+ >()))
+ .return_var(Some(Box::new({
+ let mut mock =
+ MockValueVisitor::<DynOwnedStatic<&'static str>, Blocking>::new();
+
+ mock.expect_visit()
+ .once()
+ .with(eq(OwnedStatic("Demo")))
+ .return_const(Flow::Done);
+
+ mock
+ })));
+
+ assert_eq!(
+ Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))),
+ Flow::Done
+ );
+
+ Flow::Continue
+ });
+
+ mock
+ })));
+
+ builder
+ .expect_traits_mut()
+ .times(3)
+ .in_sequence(&mut seq)
+ .return_var(None);
+
+ let value = Demo { a: true, b: false };
+
+ let walker = StructWalker::<Demo, Demo, DefaultMode, Blocking>::new(&value);
+
+ Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))).unwrap();
+}
diff --git a/tests/walkers/mod.rs b/tests/walkers/mod.rs
new file mode 100644
index 0000000..9816037
--- /dev/null
+++ b/tests/walkers/mod.rs
@@ -0,0 +1 @@
+mod core;