reworked to give trait objects higher ranked types to name them in any trait
| -rw-r--r-- | Cargo.lock | 78 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/any.rs | 374 | ||||
| -rw-r--r-- | src/any/static_wrapper.rs | 10 | ||||
| -rw-r--r-- | src/build.rs | 161 | ||||
| -rw-r--r-- | src/build/builders/core/bool.rs | 4 | ||||
| -rw-r--r-- | src/build/builders/debug.rs | 53 | ||||
| -rw-r--r-- | src/hkt.rs | 133 | ||||
| -rw-r--r-- | src/lib.rs | 110 | ||||
| -rw-r--r-- | src/protocol/visitor.rs | 3 | ||||
| -rw-r--r-- | src/protocol/visitor/recoverable.rs | 8 | ||||
| -rw-r--r-- | src/protocol/visitor/request_hint.rs | 3 | ||||
| -rw-r--r-- | src/protocol/visitor/sequence.rs | 8 | ||||
| -rw-r--r-- | src/protocol/visitor/tag.rs | 86 | ||||
| -rw-r--r-- | src/protocol/visitor/value.rs | 32 | ||||
| -rw-r--r-- | src/protocol/walker/hint.rs | 8 | ||||
| -rw-r--r-- | src/walk/walkers/core.rs | 2 | ||||
| -rw-r--r-- | src/walk/walkers/core/key_value.rs | 53 | ||||
| -rw-r--r-- | src/walk/walkers/core/struct.rs | 35 | ||||
| -rw-r--r-- | src/walk/walkers/core/tag.rs | 9 |
20 files changed, 772 insertions, 399 deletions
@@ -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", @@ -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"] } @@ -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); @@ -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] } @@ -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(()), } |