Diffstat (limited to 'src/protocol/visitor/value.rs')
| -rw-r--r-- | src/protocol/visitor/value.rs | 83 |
1 files changed, 48 insertions, 35 deletions
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs index 1ed5682..ca5d046 100644 --- a/src/protocol/visitor/value.rs +++ b/src/protocol/visitor/value.rs @@ -3,21 +3,21 @@ //! In some sense, this is the most basic protocol. use crate::{ - any::{TypeName, TypeNameable}, + any::{MaybeSized, TypeName}, + bijective_higher_ranked_type, effect::{Effect, Future}, higher_ranked_type, hkt::AnySend, - nameable, protocol::{walker::hint::HintMeta, Visitor}, Flow, }; -use super::Status; +use super::{recoverable::Recoverable, Status}; /// Trait object for the [`Value`] protocol. /// /// Types implementing the [`Value`] protocol will implement this trait. -pub trait Value<'ctx, T, E: Effect<'ctx>> { +pub trait Value<'ctx, T: MaybeSized::Trait<'ctx>, E: Effect<'ctx>> { /// Visit a value of type `T`. /// /// Use this to give a value to a visitor. Its expected that a walker @@ -27,22 +27,27 @@ pub trait Value<'ctx, 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>(&'a mut self, value: T) -> Future<'a, 'ctx, Flow, E>; + fn visit<'a>(&'a mut self, value: MaybeSized::T<'a, 'ctx, T>) -> Future<'a, 'ctx, Flow, E>; } -pub type DynValue<'a, 'ctx, T, E> = dyn Value<'ctx, T, E> + Send + 'a; - -nameable! { - pub struct Name['ctx, T, E] for<'a>; - - impl [T::Name, E] for DynValue<'a, 'ctx, T, E> where { - T: TypeNameable<'ctx> + ?Sized, +bijective_higher_ranked_type! { + pub type DynValue['ctx][T, E][]: MaybeSized['ctx][] + for<'a> + (dyn Value<'ctx, T, E> + Send + 'a) + where { E: Effect<'ctx>, + T: ?Sized + MaybeSized::Trait<'ctx> + 'ctx } +} - impl [T, E] where DynValue<'a, 'ctx, T::Nameable, E> { - T: TypeName<'ctx> + ?Sized, +bijective_higher_ranked_type! { + pub type [][E][T[][]]: TypeName[][] + for<'ctx> + (DynValue<'ctx, TypeName::T<'ctx, T>, E>) + (DynValue<'ctx, T, E>) + where { E: Effect<'ctx>, + T: ?Sized, } } @@ -51,17 +56,22 @@ higher_ranked_type! { } // This enrolls the Value protocol into the walker hint system. -impl<'a, 'ctx: 'a, T, E: Effect<'ctx>> HintMeta<'ctx> for DynValue<'a, 'ctx, T, E> { +impl<'a, 'ctx: 'a, T, E: Effect<'ctx>> HintMeta<'ctx> for DynValue<'ctx, T, E> { type Known = ValueKnownHkt<'ctx>; type Hint = (); } -pub fn visit_value<'a, 'ctx, T: TypeNameable<'ctx>, E: Effect<'ctx>>( +pub fn visit_value<'a, 'ctx, T: MaybeSized::Member<'a, 'ctx> + 'ctx, E: Effect<'ctx>>( visitor: Visitor<'a, 'ctx>, value: T, -) -> Future<'a, 'ctx, Status, E> { - if let Some(object) = visitor.upcast_mut::<DynValue<'_, 'ctx, T, E>>() { +) -> Future<'a, 'ctx, Status, E> +where + MaybeSized::HigherRanked<'a, 'ctx, T>: TypeName::Member<'ctx> + Sized, +{ + if let Some(object) = + visitor.upcast_mut::<DynValue<'ctx, MaybeSized::HigherRanked<'a, 'ctx, T>, E>>() + { // Allow the visitor to give a hint if it wants. E::map(object.visit(value), |flow| match flow { Flow::Continue => { @@ -83,11 +93,14 @@ pub fn visit_value<'a, 'ctx, T: TypeNameable<'ctx>, E: Effect<'ctx>>( #[cfg(test)] mod test { - use core::{marker::PhantomData, ops::ControlFlow}; + use core::marker::PhantomData; use crate::{ any::{ - static_wrapper::{BorrowedMutStatic, BorrowedStatic, OwnedStatic}, + static_wrapper::{ + BorrowedMutStatic, BorrowedStatic, DynBorrowedMutStatic, DynBorrowedStatic, + DynOwnedStatic, OwnedStatic, + }, AnyTrait, }, any_trait, @@ -100,7 +113,7 @@ mod test { fn visit() { struct Visitor<E>(Option<i32>, PhantomData<fn() -> E>); - impl<'ctx, E> Value<'ctx, OwnedStatic<i32>, E> for Visitor<E> + impl<'ctx, E> Value<'ctx, DynOwnedStatic<'ctx, i32>, E> for Visitor<E> where E: Effect<'ctx>, { @@ -115,7 +128,7 @@ mod test { } } - impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, i32>, E> for Visitor<E> + impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, i32>, E> for Visitor<E> where E: Effect<'ctx>, { @@ -131,9 +144,9 @@ mod test { } any_trait! { - impl['a, 'ctx, E] Visitor<E> = [ - DynValue<'a, 'ctx, OwnedStatic<i32>, E>, - DynValue<'a, 'ctx, BorrowedStatic<'ctx, i32>, E>, + impl['ctx, E] Visitor<E> = [ + DynValue<'ctx, DynOwnedStatic<'ctx, i32>, E>, + DynValue<'ctx, DynBorrowedStatic<'ctx, i32>, E>, ] where E: Effect<'ctx>, } @@ -141,7 +154,7 @@ mod test { let object: &mut (dyn AnyTrait<'_> + Send) = &mut v; Spin::block_on( object - .upcast_mut::<DynValue<'_, '_, OwnedStatic<i32>, Blocking>>() + .upcast_mut::<DynValue<'_, DynOwnedStatic<'_, i32>, Blocking>>() .unwrap() .visit(OwnedStatic(42)), ); @@ -151,7 +164,7 @@ mod test { let object: &mut (dyn AnyTrait<'_> + Send) = &mut v; Spin::block_on( object - .upcast_mut::<DynValue<'_, '_, BorrowedStatic<'_, i32>, Blocking>>() + .upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, i32>, Blocking>>() .unwrap() .visit(BorrowedStatic(&101)), ); @@ -163,7 +176,7 @@ mod test { fn visit_borrowed() { struct Visitor<'ctx, E>(Option<&'ctx mut String>, PhantomData<fn() -> E>); - impl<'ctx, E> Value<'ctx, BorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E> + impl<'ctx, E> Value<'ctx, DynBorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E> where E: Effect<'ctx>, { @@ -180,8 +193,8 @@ mod test { } any_trait! { - impl['a, 'ctx, E] Visitor<'ctx, E> = [ - DynValue<'a, 'ctx, BorrowedMutStatic<'ctx, String>, E>, + impl['ctx, E] Visitor<'ctx, E> = [ + DynValue<'ctx, DynBorrowedMutStatic<'ctx, String>, E>, ] where E: Effect<'ctx> } @@ -191,7 +204,7 @@ mod test { let object: &mut (dyn AnyTrait<'_> + Send) = &mut v; Spin::block_on( object - .upcast_mut::<DynValue<'_, '_, _, Blocking>>() + .upcast_mut::<DynValue<'_, DynBorrowedMutStatic<'_, _>, Blocking>>() .unwrap() .visit(BorrowedMutStatic(&mut y)), ); @@ -204,7 +217,7 @@ mod test { fn visit_borrowed_unsized() { struct Visitor<'ctx, E>(Option<&'ctx str>, PhantomData<fn() -> E>); - impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E> + impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E> where E: Effect<'ctx>, { @@ -220,8 +233,8 @@ mod test { } any_trait! { - impl['a, 'ctx, E] Visitor<'ctx, E> = [ - DynValue<'a, 'ctx, BorrowedStatic<'ctx, str>, E>, + impl['ctx, E] Visitor<'ctx, E> = [ + DynValue<'ctx, DynBorrowedStatic<'ctx, str>, E>, ] where E: Effect<'ctx> } @@ -231,7 +244,7 @@ mod test { let object: &mut (dyn AnyTrait<'_> + Send) = &mut v; Spin::block_on( object - .upcast_mut::<DynValue<'_, '_, BorrowedStatic<'_, str>, Blocking>>() + .upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, str>, Blocking>>() .unwrap() .visit(BorrowedStatic(&y)), ); |