reworked to give trait objects higher ranked types to name them in any trait
Konnor Andrews 2024-04-10
parent d7365d8 · commit 7ba4e87
-rw-r--r--Cargo.lock78
-rw-r--r--Cargo.toml1
-rw-r--r--src/any.rs374
-rw-r--r--src/any/static_wrapper.rs10
-rw-r--r--src/build.rs161
-rw-r--r--src/build/builders/core/bool.rs4
-rw-r--r--src/build/builders/debug.rs53
-rw-r--r--src/hkt.rs133
-rw-r--r--src/lib.rs110
-rw-r--r--src/protocol/visitor.rs3
-rw-r--r--src/protocol/visitor/recoverable.rs8
-rw-r--r--src/protocol/visitor/request_hint.rs3
-rw-r--r--src/protocol/visitor/sequence.rs8
-rw-r--r--src/protocol/visitor/tag.rs86
-rw-r--r--src/protocol/visitor/value.rs32
-rw-r--r--src/protocol/walker/hint.rs8
-rw-r--r--src/walk/walkers/core.rs2
-rw-r--r--src/walk/walkers/core/key_value.rs53
-rw-r--r--src/walk/walkers/core/struct.rs35
-rw-r--r--src/walk/walkers/core/tag.rs9
20 files changed, 772 insertions, 399 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 206724d..23e5987 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,6 +18,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
+name = "anstyle"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
+
+[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -87,6 +93,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "downcast"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"
+
+[[package]]
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -109,6 +121,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
+name = "fragile"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
+
+[[package]]
name = "getrandom"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -214,6 +232,33 @@ dependencies = [
]
[[package]]
+name = "mockall"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48"
+dependencies = [
+ "cfg-if",
+ "downcast",
+ "fragile",
+ "lazy_static",
+ "mockall_derive",
+ "predicates",
+ "predicates-tree",
+]
+
+[[package]]
+name = "mockall_derive"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2"
+dependencies = [
+ "cfg-if",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -284,6 +329,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
+name = "predicates"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8"
+dependencies = [
+ "anstyle",
+ "predicates-core",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
+[[package]]
name = "proc-macro2"
version = "1.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -505,6 +576,12 @@ dependencies = [
]
[[package]]
+name = "termtree"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
+
+[[package]]
name = "tokio"
version = "1.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -539,6 +616,7 @@ name = "treaty"
version = "0.0.1"
dependencies = [
"macro_rules_attribute",
+ "mockall",
"proptest",
"serde",
"serde_json",
diff --git a/Cargo.toml b/Cargo.toml
index 0ca50b9..1bc4f96 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,6 +20,7 @@ serde = ["dep:serde"]
[dev-dependencies]
macro_rules_attribute = "0.2.0"
+mockall = "0.12.1"
proptest = "1.4.0"
serde_json = "1.0.114"
tokio = { version = "1.36.0", features = ["full"] }
diff --git a/src/any.rs b/src/any.rs
index 178438f..4cd533c 100644
--- a/src/any.rs
+++ b/src/any.rs
@@ -19,8 +19,9 @@
//! without unsafe code. However, its recommended to use the provided [`nameable`]
//! macro when possible.
-pub mod static_wrapper;
+// pub mod static_wrapper;
+use crate::bijective_higher_ranked_trait;
use core::{
marker::{PhantomData, PhantomPinned},
mem::{ManuallyDrop, MaybeUninit},
@@ -29,158 +30,173 @@ use core::{
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
-/// A type with another type acting as its name.
-///
-/// The `'a` lifetime is the lifetime `Self` must outlive.
-/// The `'lt` lifetime is some arbitrary lifetime `Self` can use in it's definition.
-///
-/// The [`nameable`] allows implementing this trait and [`TypeName`] with minimal effort.
-/// For types that are `'static` they can be wrapped by the included wrappers in
-/// the [`static_wrapper`] module.
-///
-/// This trait is circular with [`TypeName`] on [`Self::Name`].
-/// As a result, both must be implemented with matching implementations,
-/// and each type can only be used as the name for one type.
-pub trait TypeNameable<'a, 'lt>: 'a {
- /// The type acting to name `Self`.
- ///
- /// This name type is unique to this `Self` type.
- type Name: ?Sized + TypeName<'a, 'lt, Nameable = Self>;
+bijective_higher_ranked_trait! {
+ pub type class MaybeSized['lt][]: [for<'a>]
}
-/// The pair trait to [`TypeNameable`].
-///
-/// This trait is implemented by types acting as names.
-/// Each name type can only be used to name one type.
-///
-/// This type must be `'static` so it works with [`TypeId`][core::any::TypeId].
-pub trait TypeName<'a, 'lt>: 'static {
- /// The type this type names.
- ///
- /// In some sense, this is the lifetime poisoned form of `Self`.
- type Nameable: ?Sized + TypeNameable<'a, 'lt, Name = Self>;
+bijective_higher_ranked_trait! {
+ pub type class TypeName[][]: {'static} [for<'lt> MaybeSized::Trait<'lt>]
}
-/// Implement [`TypeNameable`] and generate a unique name type.
-///
-/// ```text
-/// use treaty::any::{nameable, TypeNameable, TypeName};
-///
-/// pub struct MyType<T>(pub T);
-///
-/// nameable! {
-/// pub struct Name['a, 'lt, T];
-/// impl [T::Name] for MyType<T> where { T: TypeNameable<'a, 'lt>, T::Name: Sized }
-/// impl [T] where MyType<T::Nameable> { T: TypeName<'a, 'lt>, T::Nameable: Sized }
-/// }
-/// ```
-///
-/// The generated `Name` struct will not be nameable outside the macro.
-/// Its only purpose is to be a unique type to act as a name.
-/// The first `impl` is for [`TypeNameable`] on the type given between the `for` and `where`.
-/// The first list of generics are what will be passed to the generics of `Name`.
-/// The second `impl` is for [`TypeName`] in `Name`. The type given after the `where`
-/// needs to match the type given in the first `impl`. However, in the second impl
-/// the `T` is a generic for a name not the generic for the type. That's why
-/// `T::Nameable` is used instead of `T`.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! nameable {
+// trait Other<'lt> {}
+//
+// trait Demo<'lt> {
+// fn demo(&self) -> &'lt i32;
+// }
+//
+// bijective_higher_ranked_type! {
+// type DynDemo['lt][]: (MaybeSized)['lt][] = for<'a> dyn Demo<'lt> + 'a
+// }
+//
+// bijective_higher_ranked_type! {
+// type DemoName[][]: (TypeName)[][] = for<'lt> DynDemo<'lt>
+// }
+
+// bijective_higher_ranked_type! {
+// pub type MaybeSizedRef['lt][T]: (MaybeSized)['lt][] = for<'a> &'lt T where { T: 'lt }
+// }
+
+const _: () = {
+ pub struct Name<T: ?Sized>(PhantomData<fn() -> *const T>);
+ pub struct LowerName<'lt, T: ?Sized>(PhantomData<fn() -> (&'lt (), *const T)>);
+
+ impl<'a, 'lt, T: ?Sized + MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)>>
+ MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)> for LowerName<'lt, T>
{
- $vis:vis struct $name:ident[$a:lifetime, $lt:lifetime $(, $($generic:ident),* $(,)?)?];
-
- impl $([$($name_generics:tt)*])? for $type:ty where {$($nameable_bound:tt)*}
- } => {
- $crate::any::nameable! {
- $vis struct $name[$a, $lt $(, $($generic),*)?];
+ type T = &'a <T as MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)>>::T;
+ }
- impl $([$($name_generics)*])? for $type where {$($nameable_bound)*}
- impl $([$($name_generics)*])? where $type {$($nameable_bound)*}
- }
- };
+ impl<'a, 'lt, T: ?Sized + MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)>>
+ MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)> for &'a T
{
- $vis:vis struct $name:ident[$a:lifetime, $lt:lifetime $(, $($generic:ident),* $(,)?)?];
-
- impl $([$($name_generics:tt)*])? for $type:ty where {$($nameable_bound:tt)*}
+ type HigherRanked =
+ LowerName<'lt, <T as MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)>>::HigherRanked>;
+ }
- impl $([$($nameable_generics:tt)*])? where $nameable_type:ty {$($name_bound:tt)*}
- } => {
- const _: () = {
- $vis struct $name $(< $($generic: ?Sized),* >)?(
- ::core::marker::PhantomData<fn() -> ($( $(*const $generic,)* )?)>
- );
+ impl<'lt, T: ?Sized + TypeName::LowerForLt<'lt, &'lt ()>> TypeName::LowerForLt<'lt, &'lt ()>
+ for Name<T>
+ {
+ type T = LowerName<'lt, <T as TypeName::LowerForLt<'lt, &'lt ()>>::T>;
+ }
- impl<$a, $lt $(, $($generic),*)?>
- $crate::any::TypeNameable<$a, $lt> for $type
- where
- $($nameable_bound)*
- {
- type Name = $name $(<$($name_generics)*>)?;
- }
+ impl<'lt, T: ?Sized + 'lt + TypeName::RaiseForLt<'lt, &'lt ()>>
+ TypeName::RaiseForLt<'lt, &'lt ()> for LowerName<'lt, T>
+ {
+ type HigherRanked = Name<TypeName::HigherRanked<'lt, T>>;
+ }
+};
- impl<$a, $lt $(, $($generic),*)?>
- $crate::any::TypeName<$a, $lt> for Name$(<$($nameable_generics)*>)?
- where
- $($name_bound)*
- {
- type Nameable = $nameable_type;
- }
- };
- };
-}
-#[doc(inline)]
-pub use nameable;
+const _: () = {
+ pub struct Name<T: ?Sized>(PhantomData<fn() -> *const T>);
+ pub struct LowerName<'lt, T: ?Sized>(PhantomData<fn() -> (&'lt (), *const T)>);
-nameable! {
- pub struct Name['a, 'lt, T];
- impl [T::Name] for &'lt T where {
- T: TypeNameable<'a, 'lt> + ?Sized, 'lt: 'a
- }
- impl [T] where &'lt T::Nameable {
- T: TypeName<'a, 'lt> + ?Sized, T::Nameable: 'lt, 'lt: 'a
+ impl<'a, 'lt, T: ?Sized + MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)>>
+ MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)> for LowerName<'lt, T>
+ {
+ type T = &'a mut <T as MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)>>::T;
}
-}
-nameable! {
- pub struct Name['a, 'lt, T];
- impl [T::Name] for &'lt mut T where {
- T: TypeNameable<'a, 'lt> + ?Sized, 'lt: 'a
- }
- impl [T] where &'lt mut T::Nameable {
- T: TypeName<'a, 'lt> + ?Sized, T::Nameable: 'lt, 'lt: 'a
+ impl<'a, 'lt, T: ?Sized + MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)>>
+ MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)> for &'a mut T
+ {
+ type HigherRanked =
+ LowerName<'lt, <T as MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)>>::HigherRanked>;
}
-}
-nameable! {
- pub struct Name['a, 'lt, T];
- impl [T::Name] for *const T where {
- T: TypeNameable<'a, 'lt> + ?Sized
+ impl<'lt, T: ?Sized + TypeName::LowerForLt<'lt, &'lt ()>> TypeName::LowerForLt<'lt, &'lt ()>
+ for Name<T>
+ {
+ type T = LowerName<'lt, <T as TypeName::LowerForLt<'lt, &'lt ()>>::T>;
}
- impl [T] where *const T::Nameable {
- T: TypeName<'a, 'lt> + ?Sized
+
+ impl<'lt, T: ?Sized + 'lt + TypeName::RaiseForLt<'lt, &'lt ()>>
+ TypeName::RaiseForLt<'lt, &'lt ()> for LowerName<'lt, T>
+ {
+ type HigherRanked = Name<TypeName::HigherRanked<'lt, T>>;
}
-}
+};
+
+#[cfg(feature = "alloc")]
+const _: () = {
+ pub struct Name<T: ?Sized>(PhantomData<fn() -> *const T>);
+ pub struct LowerName<'lt, T: ?Sized>(PhantomData<fn() -> (&'lt (), *const T)>);
-nameable! {
- pub struct Name['a, 'lt, T];
- impl [T::Name] for *mut T where {
- T: TypeNameable<'a, 'lt> + ?Sized
+ impl<'a, 'lt, T: ?Sized + MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)>>
+ MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)> for LowerName<'lt, T>
+ {
+ type T = Box<<T as MaybeSized::LowerForLt<'a, 'lt, &'a (&'lt (),)>>::T>;
}
- impl [T] where *mut T::Nameable {
- T: TypeName<'a, 'lt> + ?Sized
+
+ impl<'a, 'lt, T: ?Sized + MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)>>
+ MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)> for Box<T>
+ {
+ type HigherRanked =
+ LowerName<'lt, <T as MaybeSized::RaiseForLt<'a, 'lt, &'a (&'lt (),)>>::HigherRanked>;
}
-}
-#[cfg(feature = "alloc")]
-nameable! {
- pub struct Name['a, 'lt, T];
- impl [T::Name] for Box<T> where {
- T: TypeNameable<'a, 'lt> + ?Sized
+ impl<'lt, T: ?Sized + TypeName::LowerForLt<'lt, &'lt ()>> TypeName::LowerForLt<'lt, &'lt ()>
+ for Name<T>
+ {
+ type T = LowerName<'lt, <T as TypeName::LowerForLt<'lt, &'lt ()>>::T>;
}
- impl [T] where Box<T::Nameable> {
- T: TypeName<'a, 'lt> + ?Sized
+
+ impl<'lt, T: ?Sized + 'lt + TypeName::RaiseForLt<'lt, &'lt ()>>
+ TypeName::RaiseForLt<'lt, &'lt ()> for LowerName<'lt, T>
+ {
+ type HigherRanked = Name<TypeName::HigherRanked<'lt, T>>;
}
-}
+};
+
+// nameable! {
+// pub struct Name['a, 'lt, T];
+// impl [T::ForLtName] for &'lt T where {
+// T: TypeNameableForLt<'a, 'lt, &'a &'lt ()> + ?Sized
+// }
+// impl [T] where &'lt T::ForLtNameable {
+// T: TypeNameForLt<'a, 'lt, &'a &'lt ()> + ?Sized, T::ForLtNameable: 'lt
+// }
+// }
+
+// nameable! {
+// pub struct Name['a, 'lt, T];
+// impl [<T as TypeNameableHelper<'lt>>::Name] for &'lt mut T where {
+// T: TypeNameable<'lt> + ?Sized
+// }
+// impl [T] where &'lt mut T::Nameable {
+// T: TypeNameForLt<'a, 'lt, &'a &'lt ()> + ?Sized, T::Nameable: 'lt
+// }
+// }
+//
+// nameable! {
+// pub struct Name['a, 'lt, T];
+// impl [<T as TypeNameableHelper<'lt>>::Name] for *const T where {
+// T: TypeNameable<'lt> + ?Sized
+// }
+// impl [T] where *const T::Nameable {
+// T: TypeNameForLt<'a, 'lt, &'a &'lt ()> + ?Sized
+// }
+// }
+//
+// nameable! {
+// pub struct Name['a, 'lt, T];
+// impl [<T as TypeNameableHelper<'lt>>::Name] for *mut T where {
+// T: TypeNameable<'lt> + ?Sized
+// }
+// impl [T] where *mut T::Nameable {
+// T: TypeNameForLt<'a, 'lt, &'a &'lt ()> + ?Sized
+// }
+// }
+//
+// #[cfg(feature = "alloc")]
+// nameable! {
+// pub struct Name['a, 'lt, T];
+// impl [<T as TypeNameableHelper<'lt>>::Name] for Box<T> where {
+// T: TypeNameable<'lt> + ?Sized
+// }
+// impl [T] where Box<T::Nameable> {
+// T: TypeNameForLt<'a, 'lt, &'a &'lt ()> + ?Sized
+// }
+// }
/// [`TypeId`][core::any::TypeId] with a lifetime generic `'lt`.
///
@@ -204,10 +220,10 @@ impl<'lt> LtTypeId<'lt> {
///
/// The type must implement [`TypeNameable`]. Note, the `'a` lifetime is **not**
/// tracked by the [`LtTypeId`], only the `'lt` lifetime is.
- pub fn of<'a, T: ?Sized + TypeNameable<'a, 'lt>>() -> Self {
+ pub fn of<T: ?Sized + TypeName::Member<'lt>>() -> Self {
LtTypeId {
_marker: PhantomData,
- name_id: core::any::TypeId::of::<T::Name>(),
+ name_id: core::any::TypeId::of::<TypeName::HigherRanked<'lt, T>>(),
name: core::any::type_name::<T>(),
}
}
@@ -237,10 +253,10 @@ mod sealed {
pub trait Sealed<'lt> {}
- impl<'a, 'lt, T: ?Sized + TypeNameable<'a, 'lt>> Sealed<'lt> for T {}
+ impl<'lt, T: ?Sized + TypeName::Member<'lt>> Sealed<'lt> for T {}
}
-impl<'a, 'lt, T: ?Sized + TypeNameable<'a, 'lt>> LtAny<'lt> for T {
+impl<'lt, T: ?Sized + TypeName::Member<'lt>> LtAny<'lt> for T {
fn type_id(&self) -> LtTypeId<'lt> {
LtTypeId::of::<T>()
}
@@ -248,12 +264,12 @@ impl<'a, 'lt, T: ?Sized + TypeNameable<'a, 'lt>> LtAny<'lt> for T {
impl<'a, 'lt> dyn LtAny<'lt> + 'a {
/// Check if `self` is of type `T`.
- pub fn is<T: ?Sized + TypeNameable<'a, 'lt>>(&self) -> bool {
+ pub fn is<T: ?Sized + TypeName::Member<'lt>>(&self) -> bool {
LtTypeId::of::<T>() == self.type_id()
}
/// Downcast a `&dyn LtAny<'lt>` into a `&T`.
- pub fn downcast_ref<T: TypeNameable<'a, 'lt>>(&self) -> Option<&T> {
+ pub fn downcast_ref<T: TypeName::Member<'lt>>(&self) -> Option<&T> {
if self.is::<T>() {
Some(unsafe { &*(self as *const dyn LtAny<'lt> as *const T) })
} else {
@@ -262,7 +278,7 @@ impl<'a, 'lt> dyn LtAny<'lt> + 'a {
}
/// Downcast a `&mut dyn LtAny<'lt>` into a `&mut T`.
- pub fn downcast_mut<T: TypeNameable<'a, 'lt>>(&mut self) -> Option<&mut T> {
+ pub fn downcast_mut<T: TypeName::Member<'lt>>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
Some(unsafe { &mut *(self as *mut dyn LtAny<'lt> as *mut T) })
} else {
@@ -272,7 +288,7 @@ impl<'a, 'lt> dyn LtAny<'lt> + 'a {
/// Downcast a `Box<dyn LtAny<'lt>>` into a `Box<T>`.
#[cfg(feature = "alloc")]
- pub fn downcast_box<T: TypeNameable<'a, 'lt>>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
+ pub fn downcast_box<T: TypeName::Member<'lt>>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
if self.is::<T>() {
Ok(unsafe {
let raw: *mut dyn LtAny<'lt> = Box::into_raw(self);
@@ -366,7 +382,9 @@ impl<'lt> dyn AnyTrait<'lt> + Send + '_ {
/// as it automatically downcasts the returned [`IndirectLtAny`].
///
/// If the returned [`IndirectLtAny`] is the wrong type, then a panic happens.
- pub fn upcast<'a, Trait: ?Sized + TypeNameable<'a, 'lt>>(&'a self) -> Option<&'a Trait> {
+ pub fn upcast<'a, Trait: ?Sized + TypeName::Member<'lt>>(
+ &'a self,
+ ) -> Option<&'a MaybeSized::T<'a, 'lt, Trait>> {
self.upcast_to_id(LtTypeId::of::<Trait>())
.map(|object| match object.downcast::<Trait>() {
Ok(object) => object,
@@ -385,9 +403,9 @@ impl<'lt> dyn AnyTrait<'lt> + Send + '_ {
/// as it automatically downcasts the returned [`IndirectLtAny`].
///
/// If the returned [`IndirectLtAny`] is the wrong type, then a panic happens.
- pub fn upcast_mut<'a, Trait: ?Sized + TypeNameable<'a, 'lt>>(
+ pub fn upcast_mut<'a, Trait: ?Sized + TypeName::Member<'lt>>(
&'a mut self,
- ) -> Option<&'a mut Trait> {
+ ) -> Option<&'a mut MaybeSized::T<'a, 'lt, Trait>> {
self.upcast_to_id_mut(LtTypeId::of::<Trait>())
.map(|object| match object.downcast::<Trait>() {
Ok(object) => object,
@@ -488,12 +506,14 @@ impl<'a, 'lt, I: Indirect<'a>> IndirectLtAny<'a, 'lt, I> {
/// Wrap an indirection.
///
/// The inner type `T` of the indirection is erased.
- pub fn new<T: ?Sized + TypeNameable<'a, 'lt>>(indirect: I::ForT<T>) -> Self {
+ pub fn new<T: ?Sized + TypeName::Member<'lt>>(
+ indirect: I::ForT<MaybeSized::T<'a, 'lt, T>>,
+ ) -> Self {
Self {
info: || {
(LtTypeId::of::<T>(), |raw| {
// SAFETY: This is only called in the drop impl.
- unsafe { drop(I::from_raw::<T>(raw)) }
+ unsafe { drop(I::from_raw::<MaybeSized::T<'a, 'lt, T>>(raw)) }
})
},
indirect: I::into_raw(indirect),
@@ -505,11 +525,13 @@ impl<'a, 'lt, I: Indirect<'a>> IndirectLtAny<'a, 'lt, I> {
///
/// If the type of the stored value is different, then `self` is
/// returned as is.
- pub fn downcast<T: ?Sized + TypeNameable<'a, 'lt>>(self) -> Result<I::ForT<T>, Self> {
+ pub fn downcast<T: ?Sized + TypeName::Member<'lt>>(
+ self,
+ ) -> Result<I::ForT<MaybeSized::T<'a, 'lt, T>>, Self> {
let (id, _) = (self.info)();
if id == LtTypeId::of::<T>() {
- Ok(unsafe { I::from_raw::<T>(self.indirect) })
+ Ok(unsafe { I::from_raw::<MaybeSized::T<'a, 'lt, T>>(self.indirect) })
} else {
Err(self)
}
@@ -583,6 +605,7 @@ unsafe impl<'a> Indirect<'a> for Mut {
#[cfg(feature = "alloc")]
pub use boxed::*;
+
#[cfg(feature = "alloc")]
mod boxed {
use super::*;
@@ -637,64 +660,43 @@ unsafe fn transmute<T, U>(value: T) -> U {
#[cfg(test)]
mod test {
- use super::*;
-
- #[derive(Debug, PartialEq)]
- struct X<'a>(&'a mut i32);
+ use crate::bijective_higher_ranked_type;
- nameable! {
- struct Name['a, 'lt];
- impl for X<'lt> where {'lt: 'a}
- }
+ use super::*;
#[test]
fn implementer_macro() {
- trait Z {}
-
- nameable! {
- struct Name['a, 'ctx];
- impl for dyn Z + 'a where {'ctx: 'a}
+ trait Z<'ctx> {
+ fn get(&self) -> i32;
}
- struct X<T>(T);
-
- impl<T: Clone> Z for X<T> {}
-
- any_trait! {
- impl['a, 'ctx, T: Clone] X<T> = [
- dyn Z + 'a
- ]
- }
- }
-
- #[test]
- fn any_trait_macro() {
- trait Z {
- fn num(&self) -> i32;
+ bijective_higher_ranked_type! {
+ type DynZ['ctx][]: (MaybeSized)['ctx][] = for<'a> dyn Z<'ctx> + 'a
}
- nameable! {
- struct Name['a, 'ctx];
- impl for dyn Z + 'a where {'ctx: 'a}
+ bijective_higher_ranked_type! {
+ type [][]: (TypeName)[][] = for<'lt> DynZ<'lt>
}
- struct X(i32);
+ struct X<'ctx>(&'ctx i32);
- impl Z for X {
- fn num(&self) -> i32 {
- self.0
+ impl<'ctx> Z<'ctx> for X<'ctx> {
+ fn get(&self) -> i32 {
+ *self.0
}
}
any_trait! {
- impl['a, 'ctx] X = [
- dyn Z + 'a
+ impl['a, 'ctx] X<'ctx> = [
+ DynZ<'ctx>
]
}
- let x = X(42);
- let y: &(dyn AnyTrait<'_> + Send) = &x;
- let z: &dyn Z = y.upcast().unwrap();
- assert_eq!(z.num(), 42);
+ let z = 42;
+ let x = X(&z);
+ let y = (&x as &(dyn AnyTrait<'_> + Send))
+ .upcast::<DynZ<'_>>()
+ .unwrap();
+ assert_eq!(y.get(), 42);
}
}
diff --git a/src/any/static_wrapper.rs b/src/any/static_wrapper.rs
index 511982a..dee90d6 100644
--- a/src/any/static_wrapper.rs
+++ b/src/any/static_wrapper.rs
@@ -9,7 +9,6 @@ pub struct OwnedStatic<T: ?Sized>(pub T);
nameable! {
pub struct Name['a, 'lt, T];
impl [T] for OwnedStatic<T> where { T: ?Sized + 'static }
- impl [T] where OwnedStatic<T> { T: ?Sized + 'static }
}
/// Impl of [`TypeNameable`] for `'static` types that are borrowed (`&'lt T`).
@@ -18,8 +17,7 @@ pub struct BorrowedStatic<'lt, T: ?Sized>(pub &'lt T);
nameable! {
pub struct Name['a, 'lt, T];
- impl [T] for BorrowedStatic<'lt, T> where { T: ?Sized + 'static, 'lt: 'a }
- impl [T] where BorrowedStatic<'lt, T> { T: ?Sized + 'static, 'lt: 'a }
+ impl [T] for BorrowedStatic<'lt, T> where { T: ?Sized + 'static }
}
/// Impl of [`TypeNameable`] for `'static` types that are temporarily borrowed (`&'a T`).
@@ -29,7 +27,6 @@ pub struct TempBorrowedStatic<'a, T: ?Sized>(pub &'a T);
nameable! {
pub struct Name['a, 'lt, T];
impl [T] for TempBorrowedStatic<'a, T> where { T: ?Sized + 'static }
- impl [T] where TempBorrowedStatic<'a, T> { T: ?Sized + 'static }
}
/// Impl of [`TypeNameable`] for `'static` types that are borrowed mutably (`&'lt mut T`).
@@ -38,8 +35,7 @@ pub struct BorrowedMutStatic<'lt, T: ?Sized>(pub &'lt mut T);
nameable! {
pub struct Name['a, 'lt, T];
- impl [T] for BorrowedMutStatic<'lt, T> where { T: ?Sized + 'static, 'lt: 'a }
- impl [T] where BorrowedMutStatic<'lt, T> { T: ?Sized + 'static, 'lt: 'a }
+ impl [T] for BorrowedMutStatic<'lt, T> where { T: ?Sized + 'static }
}
/// Impl of [`TypeNameable`] for `'static` types that are temporarily borrowed mutably (`&'a mut T`).
@@ -49,7 +45,6 @@ pub struct TempBorrowedMutStatic<'a, T: ?Sized>(pub &'a mut T);
nameable! {
pub struct Name['a, 'lt, T];
impl [T] for TempBorrowedMutStatic<'a, T> where { T: ?Sized + 'static }
- impl [T] where TempBorrowedMutStatic<'a, T> { T: ?Sized + 'static }
}
/// Impl of [`TypeNameable`] for `'static` types that are in a [`Box`] (`Box<T>`).
@@ -60,7 +55,6 @@ pub struct BoxedStatic<T: ?Sized>(pub Box<T>);
nameable! {
pub struct Name['a, 'lt, T];
impl [T] for BoxedStatic<T> where { T: ?Sized + 'static }
- impl [T] where BoxedStatic<T> { T: ?Sized + 'static }
}
#[derive(Debug)]
diff --git a/src/build.rs b/src/build.rs
index 24232a0..0f70423 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -52,3 +52,164 @@ pub trait Builder<'ctx, E: Effect<'ctx>>: BuilderTypes + Sized + Send {
/// This is expected to just be `self`.
fn as_visitor(&mut self) -> Visitor<'_, 'ctx>;
}
+
+#[cfg(test)]
+pub mod test {
+ use std::{collections::HashMap, sync::{Mutex, MutexGuard, PoisonError}};
+
+ use crate::{
+ any::{static_wrapper::OwnedStatic, AnyTrait, Indirect, IndirectLtAny, LtTypeId, Mut, Ref, TypeNameable}, effect::{BlockOn, Blocking, Spin}, protocol::visitor::value::{DynValue, Value}, Flow
+ };
+
+ use super::*;
+
+ use mockall::mock;
+ use mockall::predicate::eq;
+
+ pub mod mock {
+ use std::collections::HashMap;
+
+ use super::*;
+
+ mock! {
+ pub Builder<Seed: 'static, Value: 'static, Error: 'static> {
+ pub fn private_from_seed(seed: Seed) -> Self;
+ pub fn private_build(self) -> Result<Value, Error>;
+
+ // pub fn private_upcast_to_id(&self, id: LtTypeId<'static>) -> Option<Box<dyn for<'a> MockIndirect>>;
+ // pub fn private_upcast_to_id_mut(&mut self, id: LtTypeId<'static>) -> Option<Box<dyn for<'a> MockIndirect<'a, Mut>>>;
+
+ pub fn lookup(&self) -> &HashMap<LtTypeId<'static>, Box<dyn MockIndirect>>;
+ pub fn lookup_mut(&mut self) -> &mut HashMap<LtTypeId<'static>, Box<dyn MockIndirect>>;
+ }
+ }
+ }
+
+ pub type MockBuilder<Seed = (), Value = (), Error = ()> = mock::MockBuilder<Seed, Value, Error>;
+
+ trait MockIndirect: Send {
+ fn indirect(&self) -> IndirectLtAny<'_, 'static, Ref>;
+ fn indirect_mut(&mut self) -> IndirectLtAny<'_, 'static, Mut>;
+ }
+
+ impl<T: ?Sized + for<'a> TypeNameable<'a, 'static> + Send> MockIndirect for Box<T> {
+ fn indirect(&self) -> IndirectLtAny<'_, 'static, Ref> {
+ IndirectLtAny::new(self)
+ }
+
+ fn indirect_mut(&mut self) -> IndirectLtAny<'_, 'static, Mut> {
+ IndirectLtAny::new(self)
+ }
+ }
+
+ impl<Seed: Send, Value: Send, Error: Send> BuilderTypes for MockBuilder<Seed, Value, Error> {
+ type Seed = Seed;
+
+ type Error = Error;
+
+ type Value = Value;
+ }
+
+ impl<Seed, Value, Error> MockBuilder<Seed, Value, Error> {
+ pub fn lock_context<'a>() -> MutexGuard<'a, ()> {
+ static LOCK: Mutex<()> = Mutex::new(());
+ LOCK.lock().unwrap_or_else(PoisonError::into_inner)
+ }
+ }
+
+ impl<Seed: Send, Value: Send, Error: Send, E: Effect<'static>> Builder<'static, E> for MockBuilder<Seed, Value, Error> {
+ fn from_seed<'a>(seed: Self::Seed) -> Future<'a, 'static, Self, E>
+ where
+ Self: 'a,
+ {
+ E::ready(Self::private_from_seed(seed))
+ }
+
+ fn build<'a>(self) -> Future<'a, 'static, Result<Self::Value, Self::Error>, E>
+ where
+ Self: 'a,
+ {
+ E::ready(self.private_build())
+ }
+
+ fn as_visitor(&mut self) -> Visitor<'_, 'static> {
+ self
+ }
+ }
+
+ impl<Seed, Value, Error> AnyTrait<'static> for MockBuilder<Seed, Value, Error> {
+ fn upcast_to_id<'a>(
+ &'a self,
+ id: LtTypeId<'static>,
+ ) -> Option<IndirectLtAny<'a, 'static, Ref>>
+ where
+ 'static: 'a,
+ {
+ self.lookup().get(&id).map(|x| x.indirect())
+ }
+
+ fn upcast_to_id_mut<'a>(
+ &'a mut self,
+ id: LtTypeId<'static>,
+ ) -> Option<IndirectLtAny<'a, 'static, Mut>>
+ where
+ 'static: 'a,
+ {
+ self.lookup_mut().get_mut(&id).map(|x| x.indirect_mut())
+ }
+ }
+
+ mock! {
+ ValueVisitor {
+ fn private_visit(&mut self, value: OwnedStatic<i32>) -> Flow;
+ }
+ }
+
+ impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<i32>, E> for MockValueVisitor {
+ fn visit<'a>(&'a mut self, value: OwnedStatic<i32>) -> Future<'a, 'ctx, Flow, E> {
+ E::ready(self.private_visit(value))
+ }
+ }
+
+ #[test]
+ fn demo2() {
+ let _lock = MockBuilder::<(), (), ()>::lock_context();
+ let ctx = MockBuilder::<(), (), ()>::private_from_seed_context();
+
+ ctx.expect().once().returning(|_| {
+ let mut mock = MockBuilder::new();
+
+ mock.expect_lookup_mut().returning(|| {
+ let mut map = HashMap::<_, Box<dyn MockIndirect>>::new();
+
+ map.insert(
+ LtTypeId::of::<DynValue<'_, 'static, OwnedStatic<i32>, Blocking>>(),
+ Box::new(Box::new(MockValueVisitor::new()) as Box<DynValue<'_, 'static, OwnedStatic<i32>, Blocking>>)
+ );
+
+ map
+ });
+
+ mock.expect_private_build().once().returning(|| {
+ Ok(())
+ });
+
+ mock
+ });
+
+ let mut builder = Spin::block_on(<MockBuilder as Builder<Blocking>>::from_seed(()));
+
+ {
+ let visitor = <MockBuilder as Builder<Blocking>>::as_visitor(&mut builder);
+
+ let x = visitor.upcast_to_id_mut(LtTypeId::of::<DynValue<'_, '_, OwnedStatic<i32>, Blocking>>()).unwrap();
+ let Ok(x) = x.downcast::<DynValue<'_, '_, OwnedStatic<i32>, Blocking>>() else {
+ panic!();
+ };
+ Spin::block_on(x.visit(OwnedStatic(42)));
+ }
+
+ let x = <MockBuilder as Builder<Blocking>>::build(builder);
+ todo!();
+ }
+}
diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs
index 7a95820..e00e674 100644
--- a/src/build/builders/core/bool.rs
+++ b/src/build/builders/core/bool.rs
@@ -65,9 +65,9 @@ any_trait! {
] where E: Effect<'ctx>
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<bool>, E> for Builder<E> {
+impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<bool>, E> for Builder<E> {
#[inline]
- fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, 'ctx, Flow, E> {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, 'ctx, Flow, E> {
self.0 = Some(value);
E::ready(Flow::Continue)
}
diff --git a/src/build/builders/debug.rs b/src/build/builders/debug.rs
index cd144d8..4957ba9 100644
--- a/src/build/builders/debug.rs
+++ b/src/build/builders/debug.rs
@@ -11,7 +11,8 @@ use crate::{
request_hint::{DynRequestHint, RequestHint},
sequence::{DynSequence, Sequence},
tag::{DynTag, Tag, TagDyn},
- value::{DynValue, Value}, Status,
+ value::{DynValue, Value},
+ Status,
},
},
DynWalker, Flow,
@@ -75,46 +76,44 @@ impl<'ctx, E: Effect<'ctx>> Tag<'ctx, TagDyn, E> for Visitor<E> {
crate::TAG_TYPE_NAME => {
self.tab();
println!("type name:");
-
+
self.0 += 1;
walker.walk(self).await;
self.0 -= 1;
-
+
Status::r#continue()
- },
+ }
crate::TAG_KEY => {
self.tab();
println!("key:");
-
+
self.0 += 1;
walker.walk(self).await;
self.0 -= 1;
-
+
Status::r#continue()
- },
+ }
crate::TAG_VALUE => {
self.tab();
println!("value:");
-
+
self.0 += 1;
walker.walk(self).await;
self.0 -= 1;
-
+
Status::r#continue()
- },
- _ => Status::skipped()
+ }
+ _ => Status::skipped(),
}
})
}
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<&'static str>, E> for Visitor<E> {
- fn visit(
+impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<&'static str>, E> for Visitor<E> {
+ fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<&'static str>,
) -> Future<'a, 'ctx, Flow, E>
- where
- Self: 'a,
{
self.tab();
println!("{:?}", value);
@@ -122,10 +121,8 @@ impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<&'static str>, E
}
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<usize>, E> for Visitor<E> {
- fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<usize>) -> Future<'a, 'ctx, Flow, E>
- where
- Self: 'a,
+impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<usize>, E> for Visitor<E> {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<usize>) -> Future<'a, 'ctx, Flow, E>
{
self.tab();
println!("{}", value);
@@ -133,10 +130,8 @@ impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<usize>, E> for V
}
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<bool>, E> for Visitor<E> {
- fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, 'ctx, Flow, E>
- where
- Self: 'a,
+impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<bool>, E> for Visitor<E> {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Future<'a, 'ctx, Flow, E>
{
self.tab();
println!("{}", value);
@@ -144,15 +139,13 @@ impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<bool>, E> for Vi
}
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<&'static [&'static str]>, E>
+impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<&'static [&'static str]>, E>
for Visitor<E>
{
- fn visit(
+ fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<&'static [&'static str]>,
) -> Future<'a, 'ctx, Flow, E>
- where
- Self: 'a,
{
self.tab();
println!("{:?}", value);
@@ -160,10 +153,8 @@ impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<&'static [&'stat
}
}
-impl<'a, 'ctx: 'a, E: Effect<'ctx>> Value<'a, 'ctx, OwnedStatic<TypeId>, E> for Visitor<E> {
- fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<TypeId>) -> Future<'a, 'ctx, Flow, E>
- where
- Self: 'a,
+impl<'ctx, E: Effect<'ctx>> Value<'ctx, OwnedStatic<TypeId>, E> for Visitor<E> {
+ fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<TypeId>) -> Future<'a, 'ctx, Flow, E>
{
self.tab();
println!("Visit type ID: {:?}", value);
diff --git a/src/hkt.rs b/src/hkt.rs
index 466d358..3f2c52d 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -49,7 +49,7 @@ macro_rules! higher_ranked_trait {
where $($($bound)*)? $($($for_bound)*)?
{
- type T$(: $($provides)+)?;
+ type T: $lt $(+ $($provides)+)?;
}
pub trait Trait<$ctx $(, $($generic)*)?>: for<$lt> ForLt<$lt, $ctx, $crate::hkt::Bound<$lt, $ctx $(, $($generic)*)?> $(, $($generic)*)?>
@@ -68,6 +68,8 @@ macro_rules! higher_ranked_trait {
};
}
+use core::marker::PhantomData;
+
#[doc(inline)]
pub use higher_ranked_trait;
@@ -94,6 +96,135 @@ macro_rules! higher_ranked_type {
#[doc(inline)]
pub use higher_ranked_type;
+#[doc(hidden)]
+#[macro_export]
+macro_rules! bijective_higher_ranked_trait {
+ {
+ $vis:vis type class $name:ident[
+ $($lifetimes:lifetime),*
+ ][
+ $($generic:ident),*
+ ]: $({$($self_provides: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 LowerForLt<$lt, $($lifetimes,)* B, $($generic),*> $(: $($self_provides)*)?
+ where $($($bound)*)? $($($for_bound)*)?
+
+ {
+ type T: ?Sized + RaiseForLt<$lt, $($lifetimes,)* B, $($generic),*> $(+ $($provides)+)? + $lt;
+ }
+
+ pub trait RaiseForLt<$lt, $($lifetimes,)* B, $($generic),*>
+ where $($($bound)*)? $($($for_bound)*)?
+
+ {
+ type HigherRanked: ?Sized + LowerForLt<$lt, $($lifetimes,)* B, $($generic),*>;
+ }
+
+ pub trait Trait<$($lifetimes,)* $($generic),*>:
+ for<$lt> LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>
+ where
+ $($($bound)*)?
+ {}
+
+ impl<$($lifetimes,)* __: ?Sized, $($generic),*> Trait<$($lifetimes,)* $($generic),*> for __
+ where
+ __: for<$lt> LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>,
+ $($($bound)*)?
+ {}
+
+ pub type T<$lt, $($lifetimes,)* __, $($generic),*> = <__ as LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>>::T;
+
+ pub trait Member<$lt, $($lifetimes,)* $($generic),*>: RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*> $(+ $($provides)+)?
+ where
+ ($(&$lifetimes (),)*): $lt,
+ $($($bound)*)?
+ {}
+
+ impl<$lt, $($lifetimes,)* __: ?Sized, $($generic),*> Member<$lt, $($lifetimes,)* $($generic),*> for __
+ where
+ __: RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*> $(+ $($provides)+)?,
+ ($(&$lifetimes (),)*): $lt,
+ $($($bound)*)?
+ {}
+
+ pub type HigherRanked<$lt, $($lifetimes,)* __, $($generic),*> = <__ as RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>>::HigherRanked;
+ }
+ };
+}
+
+#[doc(inline)]
+pub use bijective_higher_ranked_trait;
+
+/// Generate a higher-ranked type.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! bijective_higher_ranked_type {
+ {
+ $vis:vis type $name:ident[
+ $($ctx:lifetime),*
+ ][
+ $($generic:ident),*
+ ]: ($($type_class:tt)*)[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
+ $(where {$($bound:tt)*})?
+ = for<$lt:lifetime> $for_lt_type:ty
+ $(where {$($higher_bound:tt)*})?
+ } => {
+ $vis struct $name<$($type_class_lifetime,)* $($generic),*>(core::marker::PhantomData<fn() -> ($(&$type_class_lifetime (),)* $($generic,)*)>);
+
+ impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::LowerForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $($generic,)*), $($type_class_generic),*> for $name<$($type_class_lifetime,)* $($generic),*>
+ where $($($bound)*)? $($($higher_bound)*)?
+ {
+ type T = $for_lt_type;
+ }
+
+ impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::RaiseForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $($generic,)*), $($type_class_generic),*> for $for_lt_type
+ where $($($bound)*)? $($($higher_bound)*)?
+ {
+ type HigherRanked = $name<$($type_class_lifetime,)* $($generic),*>;
+ }
+ };
+ {
+ $vis:vis type [
+ $($ctx:lifetime),*
+ ][
+ $($generic:ident),*
+ ]: ($($type_class:tt)*)[$($type_class_lifetime:lifetime)*][$($type_class_generic:ident)*]
+ $(where {$($bound:tt)*})?
+ = for<$lt:lifetime> $for_lt_type:ty
+ $(where {$($higher_bound:tt)*})?
+ } => {
+ const _: () = {
+ $vis struct __Name<$($type_class_lifetime,)* $($generic: ?Sized),*>(core::marker::PhantomData<fn() -> ($(&$type_class_lifetime (),)* $(*const $generic),*)>);
+
+ impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::LowerForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $(*const $generic),*), $($type_class_generic),*> for __Name<$($type_class_lifetime,)* $($generic),*>
+ where $($($bound)*)? $($($higher_bound)*)?
+ {
+ type T = $for_lt_type;
+ }
+
+ impl<$lt, $($ctx,)* $($generic),*> $($type_class)*::RaiseForLt<$lt, $($type_class_lifetime,)* &$lt ($(&$type_class_lifetime (),)* $(*const $generic),*), $($type_class_generic),*> for $for_lt_type
+ where $($($bound)*)? $($($higher_bound)*)?
+ {
+ type HigherRanked = __Name<$($type_class_lifetime,)* $($generic),*>;
+ }
+ };
+ }
+}
+
+#[doc(inline)]
+pub use bijective_higher_ranked_type;
+
higher_ranked_trait! {
pub type class AnySend['ctx]: [for<'lt> Send]
}
diff --git a/src/lib.rs b/src/lib.rs
index f444735..22d1433 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,15 +8,13 @@
extern crate alloc;
pub mod any;
-mod build;
+// mod build;
pub mod effect;
pub mod hkt;
-pub mod protocol;
+// pub mod protocol;
pub mod symbol;
-mod walk;
-
-// pub mod impls;
-mod transform;
+// mod walk;
+// mod transform;
// pub use build::Build;
// pub use build::Builder;
@@ -26,12 +24,12 @@ mod transform;
use core::ops::ControlFlow;
-pub use build::*;
-use effect::{Effect, Future};
-use protocol::{visitor::tag::TagError, Visitor};
+// pub use build::*;
+// use effect::{Effect, Future};
+// use protocol::{visitor::tag::TagError, Visitor};
use symbol::Symbol;
-pub use transform::*;
-pub use walk::*;
+// pub use transform::*;
+// pub use walk::*;
// #[doc(hidden)]
pub mod macros;
@@ -139,7 +137,7 @@ macro_rules! Walk {
let key_walker = $crate::walkers::core::value::ValueWalker::new(stringify!($field));
let value_walker = <&'ctx $type as $crate::Walk::<'ctx, M, E>>::into_walker(&value.$field);
-
+
let walker = $crate::walkers::core::key_value::KeyValueWalker::<$crate::protocol::visitor::tag::TagConst<{ $crate::TAG_FIELD.to_int() }>, _, _>::new($crate::protocol::visitor::tag::TagConst, key_walker, value_walker);
E::map($crate::Walker::<'ctx, E>::walk(walker, visitor), |result| match result {
@@ -164,48 +162,48 @@ pub struct Demo {
pub b: bool,
}
-Walk! {
- pub struct Demo {
- a: bool,
- b: bool,
- }
-}
-
-#[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 },
- };
+// Walk! {
+// pub struct Demo {
+// a: bool,
+// b: bool,
+// }
+// }
- 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/protocol/visitor.rs b/src/protocol/visitor.rs
index 9fc98c0..de31813 100644
--- a/src/protocol/visitor.rs
+++ b/src/protocol/visitor.rs
@@ -10,7 +10,7 @@ pub enum Status<S = ()> {
/// The protocol was not used.
Skipped(S),
- Flow(Flow)
+ Flow(Flow),
}
impl<S> Status<S> {
@@ -38,4 +38,3 @@ impl From<Flow> for Status {
Status::Flow(value)
}
}
-
diff --git a/src/protocol/visitor/recoverable.rs b/src/protocol/visitor/recoverable.rs
index f2d12f7..3ed49d3 100644
--- a/src/protocol/visitor/recoverable.rs
+++ b/src/protocol/visitor/recoverable.rs
@@ -19,16 +19,10 @@ pub trait Recoverable<'ctx, E: Effect<'ctx>> {
pub type DynRecoverable<'a, 'ctx, E> = &'a mut (dyn Recoverable<'ctx, E> + Send + 'a);
nameable! {
- pub struct Name['a, 'ctx, E];
+ pub struct Name['ctx, E] for<'a>;
impl [E] for DynRecoverable<'a, 'ctx, E> where {
E: Effect<'ctx>,
- 'ctx: 'a
- }
-
- impl [E] where DynRecoverable<'a, 'ctx, E> {
- E: Effect<'ctx>,
- 'ctx: 'a
}
}
diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs
index f70fc29..516dffa 100644
--- a/src/protocol/visitor/request_hint.rs
+++ b/src/protocol/visitor/request_hint.rs
@@ -17,10 +17,9 @@ pub trait RequestHint<'ctx, E: Effect<'ctx>> {
pub type DynRequestHint<'a, 'ctx, E> = dyn RequestHint<'ctx, E> + Send + 'a;
nameable! {
- pub struct Name['a, 'ctx, E];
+ pub struct Name['ctx, E] for <'a>;
impl [E] for DynRequestHint<'a, 'ctx, E> where {
E: Effect<'ctx>,
- 'ctx: 'a
}
}
diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs
index d313e5b..2f8735d 100644
--- a/src/protocol/visitor/sequence.rs
+++ b/src/protocol/visitor/sequence.rs
@@ -16,16 +16,10 @@ pub trait Sequence<'ctx, E: Effect<'ctx>> {
pub type DynSequence<'a, 'ctx, E> = dyn Sequence<'ctx, E> + Send + 'a;
nameable! {
- pub struct Name['a, 'ctx, E];
+ pub struct Name['ctx, E] for<'a>;
impl [E] for DynSequence<'a, 'ctx, E> where {
E: Effect<'ctx>,
- 'ctx: 'a
- }
-
- impl [E] where DynSequence<'a, 'ctx, E> {
- E: Effect<'ctx>,
- 'ctx: 'a
}
}
diff --git a/src/protocol/visitor/tag.rs b/src/protocol/visitor/tag.rs
index 6a4fc1e..57cc4dc 100644
--- a/src/protocol/visitor/tag.rs
+++ b/src/protocol/visitor/tag.rs
@@ -49,18 +49,11 @@ pub trait Tag<'ctx, K: TagKind, E: Effect<'ctx>> {
pub type DynTag<'a, 'ctx, K, E> = dyn Tag<'ctx, K, E> + Send + 'a;
nameable! {
- pub struct Name['a, 'ctx, K, E];
+ pub struct Name['ctx, K, E] for<'a>;
impl [K, E] for DynTag<'a, 'ctx, K, E> where {
K: TagKind,
E: Effect<'ctx>,
- 'ctx: 'a
- }
-
- impl [K, E] where DynTag<'a, 'ctx, K, E> {
- K: TagKind,
- E: Effect<'ctx>,
- 'ctx: 'a
}
}
@@ -140,59 +133,52 @@ where
W: WalkerTypes,
{
E::wrap(async move {
- let (flow, walker) =
- if let Some(object) = visitor.upcast_mut::<DynTag<'_, 'ctx, K, E>>() {
- // The visitor knows about this tag.
+ let (flow, walker) = if let Some(object) = visitor.upcast_mut::<DynTag<'_, 'ctx, K, E>>() {
+ // The visitor knows about this tag.
+
+ // Wrap the walker to allow it to be passed to a dyn walker argument.
+ let mut walker = DynWalkerAdapter::new(walker);
+
+ // Visit the tag.
+ let flow = object.visit(kind, &mut walker).await;
+
+ (flow.into(), walker)
+ } else if core::any::TypeId::of::<TagDyn>() != core::any::TypeId::of::<K>() {
+ // Try the dynamic form if we didn't already.
+ if let Some(object) = visitor.upcast_mut::<DynTag<'_, 'ctx, TagDyn, E>>() {
+ // The visitor can handle dynamic tags.
+ // If the visitor can't handle the tag kind then it can call .skip on the walker
+ // to disable the error for not walking it.
// Wrap the walker to allow it to be passed to a dyn walker argument.
let mut walker = DynWalkerAdapter::new(walker);
// Visit the tag.
- let flow = object.visit(kind, &mut walker).await;
-
- (flow.into(), walker)
- } else if core::any::TypeId::of::<TagDyn>() != core::any::TypeId::of::<K>() {
- // Try the dynamic form if we didn't already.
- if let Some(object) = visitor.upcast_mut::<DynTag<'_, 'ctx, TagDyn, E>>() {
- // The visitor can handle dynamic tags.
- // If the visitor can't handle the tag kind then it can call .skip on the walker
- // to disable the error for not walking it.
-
- // Wrap the walker to allow it to be passed to a dyn walker argument.
- let mut walker = DynWalkerAdapter::new(walker);
-
- // Visit the tag.
- let flow = object
- .visit(TagDyn(kind.symbol()), &mut walker)
- .await;
-
- (flow, walker)
- } else {
- return Ok(Status::Skipped(walker));
- }
+ let flow = object.visit(TagDyn(kind.symbol()), &mut walker).await;
+
+ (flow, walker)
} else {
return Ok(Status::Skipped(walker));
- };
+ }
+ } else {
+ return Ok(Status::Skipped(walker));
+ };
match flow {
// The walker was skipped.
- Status::Skipped(()) => {
- match walker.into_innter() {
- Ok(walker) => Ok(Status::Skipped(walker)),
- Err(DynWalkerError::Walker(err)) => Err(TagError::new(kind, err)),
- Err(DynWalkerError::NeverWalked(_)) => Err(TagError::never_walked(kind)),
- Err(DynWalkerError::WalkNeverFinished) => Err(TagError::walk_never_finished(kind)),
- Err(DynWalkerError::WasWalked(_)) => Err(TagError::was_walked(kind)),
- }
+ Status::Skipped(()) => match walker.into_innter() {
+ Ok(walker) => Ok(Status::Skipped(walker)),
+ Err(DynWalkerError::Walker(err)) => Err(TagError::new(kind, err)),
+ Err(DynWalkerError::NeverWalked(_)) => Err(TagError::never_walked(kind)),
+ Err(DynWalkerError::WalkNeverFinished) => Err(TagError::walk_never_finished(kind)),
+ Err(DynWalkerError::WasWalked(_)) => Err(TagError::was_walked(kind)),
},
- Status::Flow(flow) => {
- match walker.finish() {
- Ok(_) => Ok(Status::Flow(flow)),
- Err(DynWalkerError::Walker(err)) => Err(TagError::new(kind, err)),
- Err(DynWalkerError::NeverWalked(_)) => Err(TagError::never_walked(kind)),
- Err(DynWalkerError::WalkNeverFinished) => Err(TagError::walk_never_finished(kind)),
- Err(DynWalkerError::WasWalked(_)) => Err(TagError::was_walked(kind)),
- }
+ Status::Flow(flow) => match walker.finish() {
+ Ok(_) => Ok(Status::Flow(flow)),
+ Err(DynWalkerError::Walker(err)) => Err(TagError::new(kind, err)),
+ Err(DynWalkerError::NeverWalked(_)) => Err(TagError::never_walked(kind)),
+ Err(DynWalkerError::WalkNeverFinished) => Err(TagError::walk_never_finished(kind)),
+ Err(DynWalkerError::WasWalked(_)) => Err(TagError::was_walked(kind)),
},
}
})
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index 3e9a3bc..1ed5682 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -17,7 +17,7 @@ use super::Status;
/// Trait object for the [`Value`] protocol.
///
/// Types implementing the [`Value`] protocol will implement this trait.
-pub trait Value<'a, 'ctx: 'a, T, E: Effect<'ctx>> {
+pub trait Value<'ctx, T, E: Effect<'ctx>> {
/// Visit a value of type `T`.
///
/// Use this to give a value to a visitor. Its expected that a walker
@@ -27,24 +27,22 @@ pub trait Value<'a, 'ctx: 'a, T, 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 mut self, value: T) -> Future<'a, 'ctx, Flow, E>;
+ fn visit<'a>(&'a mut self, value: T) -> Future<'a, 'ctx, Flow, E>;
}
-pub type DynValue<'a, 'ctx, T, E> = dyn Value<'a, 'ctx, T, E> + Send + 'a;
+pub type DynValue<'a, 'ctx, T, E> = dyn Value<'ctx, T, E> + Send + 'a;
nameable! {
- pub struct Name['a, 'ctx, T, E];
+ pub struct Name['ctx, T, E] for<'a>;
impl [T::Name, E] for DynValue<'a, 'ctx, T, E> where {
- T: TypeNameable<'a, 'ctx> + ?Sized,
+ T: TypeNameable<'ctx> + ?Sized,
E: Effect<'ctx>,
- 'ctx: 'a,
}
impl [T, E] where DynValue<'a, 'ctx, T::Nameable, E> {
- T: TypeName<'a, 'ctx> + ?Sized,
+ T: TypeName<'ctx> + ?Sized,
E: Effect<'ctx>,
- 'ctx: 'a,
}
}
@@ -59,7 +57,7 @@ impl<'a, 'ctx: 'a, T, E: Effect<'ctx>> HintMeta<'ctx> for DynValue<'a, 'ctx, T,
type Hint = ();
}
-pub fn visit_value<'a, 'ctx, T: TypeNameable<'a, 'ctx>, E: Effect<'ctx>>(
+pub fn visit_value<'a, 'ctx, T: TypeNameable<'ctx>, E: Effect<'ctx>>(
visitor: Visitor<'a, 'ctx>,
value: T,
) -> Future<'a, 'ctx, Status, E> {
@@ -102,11 +100,11 @@ mod test {
fn visit() {
struct Visitor<E>(Option<i32>, PhantomData<fn() -> E>);
- impl<'a, 'ctx: 'a, E> Value<'a, 'ctx, OwnedStatic<i32>, E> for Visitor<E>
+ impl<'ctx, E> Value<'ctx, OwnedStatic<i32>, E> for Visitor<E>
where
E: Effect<'ctx>,
{
- fn visit(
+ fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<i32>,
) -> Future<'a, 'ctx, Flow, E> {
@@ -117,11 +115,11 @@ mod test {
}
}
- impl<'a, 'ctx: 'a, E> Value<'a, 'ctx, BorrowedStatic<'ctx, i32>, E> for Visitor<E>
+ impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, i32>, E> for Visitor<E>
where
E: Effect<'ctx>,
{
- fn visit(
+ fn visit<'a>(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, i32>,
) -> Future<'a, 'ctx, Flow, E> {
@@ -165,11 +163,11 @@ mod test {
fn visit_borrowed() {
struct Visitor<'ctx, E>(Option<&'ctx mut String>, PhantomData<fn() -> E>);
- impl<'a, 'ctx: 'a, E> Value<'a, 'ctx, BorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E>
+ impl<'ctx, E> Value<'ctx, BorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E>
where
E: Effect<'ctx>,
{
- fn visit(
+ fn visit<'a>(
&'a mut self,
BorrowedMutStatic(value): BorrowedMutStatic<'ctx, String>,
) -> Future<'a, 'ctx, Flow, E> {
@@ -206,11 +204,11 @@ mod test {
fn visit_borrowed_unsized() {
struct Visitor<'ctx, E>(Option<&'ctx str>, PhantomData<fn() -> E>);
- impl<'a, 'ctx: 'a, E> Value<'a, 'ctx, BorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E>
+ impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E>
where
E: Effect<'ctx>,
{
- fn visit(
+ fn visit<'a>(
&'a mut self,
BorrowedStatic(value): BorrowedStatic<'ctx, str>,
) -> Future<'a, 'ctx, Flow, E> {
diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs
index 16b2515..1ec93b4 100644
--- a/src/protocol/walker/hint.rs
+++ b/src/protocol/walker/hint.rs
@@ -52,18 +52,16 @@ pub trait Hint<'a, 'ctx: 'a, Protocol: ?Sized + HintMeta<'ctx>, E: Effect<'ctx>>
pub type DynHint<'a, 'ctx, Protocol, E> = dyn Hint<'a, 'ctx, Protocol, E> + Send + 'a;
nameable! {
- pub struct Name['a, 'ctx, Protocol, E];
+ pub struct Name['ctx, Protocol, E] for<'a>;
impl [Protocol::Name, E] for DynHint<'a, 'ctx, Protocol, E> where {
- Protocol: TypeNameable<'a, 'ctx> + ?Sized,
+ Protocol: TypeNameable<'ctx> + ?Sized,
E: Effect<'ctx>,
- 'ctx: 'a,
}
impl [Protocol, E] where DynHint<'a, 'ctx, Protocol::Nameable, E> {
- Protocol: TypeName<'a, 'ctx> + ?Sized,
+ Protocol: TypeName<'ctx> + ?Sized,
E: Effect<'ctx>,
- 'ctx: 'a,
}
}
diff --git a/src/walk/walkers/core.rs b/src/walk/walkers/core.rs
index b1cc7af..6b6b128 100644
--- a/src/walk/walkers/core.rs
+++ b/src/walk/walkers/core.rs
@@ -1,8 +1,8 @@
// pub mod array;
pub mod bool;
+pub mod key_value;
pub mod noop;
pub mod r#struct;
pub mod tag;
pub mod value;
-pub mod key_value;
diff --git a/src/walk/walkers/core/key_value.rs b/src/walk/walkers/core/key_value.rs
index 3ac5b6b..6eb2210 100644
--- a/src/walk/walkers/core/key_value.rs
+++ b/src/walk/walkers/core/key_value.rs
@@ -1,4 +1,16 @@
-use crate::{never::Never, WalkerTypes, effect::{Effect, Future}, protocol::{Visitor, visitor::{tag::{visit_tag, TagKind, TagConst, TagError}, Status}}, walkers::core::noop::NoopWalker, TAG_KEY_VALUE, Flow, TAG_KEY, TAG_VALUE};
+use crate::{
+ effect::{Effect, Future},
+ never::Never,
+ protocol::{
+ visitor::{
+ tag::{visit_tag, TagConst, TagError, TagKind},
+ Status,
+ },
+ Visitor,
+ },
+ walkers::core::noop::NoopWalker,
+ Flow, WalkerTypes, TAG_KEY, TAG_KEY_VALUE, TAG_VALUE,
+};
pub struct KeyValueWalker<T, K, V> {
key_walker: K,
@@ -26,7 +38,7 @@ enum KeyValueErrorKind<K, V> {
#[derive(Debug)]
pub struct KeyValueError<K, V>(KeyValueErrorKind<K, V>);
-impl<T, K, V> WalkerTypes for KeyValueWalker<T, K, V>
+impl<T, K, V> WalkerTypes for KeyValueWalker<T, K, V>
where
K: WalkerTypes,
V: WalkerTypes,
@@ -36,7 +48,7 @@ where
type Output = ();
}
-impl<'ctx, T, K, V, E> crate::Walker<'ctx, E> for KeyValueWalker<T, K, V>
+impl<'ctx, T, K, V, E> crate::Walker<'ctx, E> for KeyValueWalker<T, K, V>
where
E: Effect<'ctx>,
T: TagKind,
@@ -48,40 +60,55 @@ where
visitor: Visitor<'a, 'ctx>,
) -> Future<'a, 'ctx, Result<Self::Output, Self::Error>, E>
where
- Self: 'a
+ Self: 'a,
{
E::wrap(async move {
match visit_tag::<T, E, _>(self.tag, visitor, NoopWalker::new()).await {
Ok(Status::Skipped(_)) => {
- match visit_tag::<TagConst<{ TAG_KEY_VALUE.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()).await
+ match visit_tag::<TagConst<{ TAG_KEY_VALUE.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ NoopWalker::new(),
+ )
+ .await
{
- Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {},
+ Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {}
Ok(Status::Flow(flow)) => return Ok(()),
Err(_) => todo!(),
}
}
- Ok(Status::Flow(Flow::Continue)) => {},
+ Ok(Status::Flow(Flow::Continue)) => {}
Ok(Status::Flow(flow)) => todo!(),
Err(_) => todo!(),
}
- match visit_tag::<TagConst<{ TAG_KEY.to_int() }>, E, _>(TagConst, visitor, self.key_walker).await
+ match visit_tag::<TagConst<{ TAG_KEY.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ self.key_walker,
+ )
+ .await
{
- Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {},
+ Ok(Status::Skipped(_) | Status::Flow(Flow::Continue)) => {}
Ok(Status::Flow(flow)) => return Ok(()),
Err(_) => todo!(),
}
- match visit_tag::<TagConst<{ TAG_VALUE.to_int() }>, E, _>(TagConst, visitor, self.value_walker).await
+ match visit_tag::<TagConst<{ TAG_VALUE.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ self.value_walker,
+ )
+ .await
{
- Ok(Status::Flow(Flow::Continue)) => {},
+ Ok(Status::Flow(Flow::Continue)) => {}
Ok(Status::Skipped(value_walker)) => {
// Fallback to just walking the value.
match value_walker.walk(visitor).await {
- Ok(_) => {},
+ Ok(_) => {}
Err(err) => todo!(),
}
- },
+ }
Ok(Status::Flow(flow)) => todo!(),
Err(_) => todo!(),
}
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs
index a07557f..a7d7e88 100644
--- a/src/walk/walkers/core/struct.rs
+++ b/src/walk/walkers/core/struct.rs
@@ -241,7 +241,11 @@ where
_hint: <DynTag<'a, 'ctx, TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta<'ctx>>::Hint,
) -> Future<'a, 'ctx, Flow, E> {
E::map(
- visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(TagConst, visitor, ValueWalker::new(I::NAME)),
+ visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ ValueWalker::new(I::NAME),
+ ),
|status| match status {
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
@@ -323,7 +327,11 @@ where
_hint: <DynTag<'a, 'ctx, TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta<'ctx>>::Hint,
) -> Future<'a, 'ctx, Flow, E> {
E::map(
- visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()),
+ visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ NoopWalker::new(),
+ ),
|status| match status {
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
@@ -590,9 +598,20 @@ where
Ok(Status::Flow(flow)) => return flow,
}
- match visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()).await {
+ match visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ NoopWalker::new(),
+ )
+ .await
+ {
Ok(Status::Skipped(_)) => {
- match visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()).await
+ match visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ NoopWalker::new(),
+ )
+ .await
{
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
@@ -610,8 +629,12 @@ where
Ok(Status::Flow(flow)) => return flow,
}
- match visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(TagConst, visitor, ValueWalker::new(I::NAME))
- .await
+ match visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(
+ TagConst,
+ visitor,
+ ValueWalker::new(I::NAME),
+ )
+ .await
{
Err(err) => {
self.error = Some(StructWalkErrorKind::Tag(err));
diff --git a/src/walk/walkers/core/tag.rs b/src/walk/walkers/core/tag.rs
index 8ad92ec..9362f6c 100644
--- a/src/walk/walkers/core/tag.rs
+++ b/src/walk/walkers/core/tag.rs
@@ -58,14 +58,13 @@ where
{
E::wrap(async move {
match visit_request_hint::<E>(visitor, &mut self).await {
- Flow::Continue => {},
+ Flow::Continue => {}
_ => return Ok(()),
}
- match visit_value::<_, E>(visitor, OwnedStatic(self.names)).await
- {
- Status::Skipped(_) => {},
- Status::Flow(Flow::Continue) => {},
+ match visit_value::<_, E>(visitor, OwnedStatic(self.names)).await {
+ Status::Skipped(_) => {}
+ Status::Flow(Flow::Continue) => {}
_ => return Ok(()),
}