Diffstat (limited to 'src/protocol/visitor/value.rs')
| -rw-r--r-- | src/protocol/visitor/value.rs | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs index 5a6a2d8..b2ae696 100644 --- a/src/protocol/visitor/value.rs +++ b/src/protocol/visitor/value.rs @@ -3,7 +3,14 @@ //! In some sense, this is the most basic protocol. use crate::{ - any::{TypeName}, effect::{Effect, Future}, higher_ranked_type, hkt::Marker, protocol::{walker::hint::{HintKnown, HintMeta}, Visitor} + any::TypeName, + effect::{Effect, Future}, + higher_ranked_type, + hkt::Marker, + protocol::{ + walker::hint::{HintKnown, HintMeta}, + Visitor, + }, }; use super::VisitResult; @@ -35,13 +42,13 @@ pub struct ValueProto<T: ?Sized + TypeName::MemberType, E: Effect>(Marker<(*cons higher_ranked_type! { impl TypeName { impl['a, 'ctx, T, E] type T['a, 'ctx] for ValueProto<T, E> = - dyn Value<'ctx, T, E> + Send + 'a + dyn Value<'ctx, T, E> + Send + Sync + 'a where { T: ?Sized + TypeName::MemberType, E: Effect }; - impl['a, 'ctx, T, E] type HigherRanked['a, 'ctx] for dyn Value<'ctx, T, E> + Send + 'a = + impl['a, 'ctx, T, E] type HigherRanked['a, 'ctx] for dyn Value<'ctx, T, E> + Send + Sync + 'a = ValueProto<T, E> where { T: ?Sized + TypeName::MemberType, @@ -50,21 +57,36 @@ higher_ranked_type! { } } -pub struct ValueKnown; +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct ValueKnown<'a, T: ?Sized> { + /// A preview of the value. + /// + /// This can be used to inspect the value before committing to a visit. + pub preview: Option<&'a T>, +} + +#[derive(Copy, Clone, Debug)] +pub struct ValueKnownHrt<T: ?Sized>(Marker<T>); higher_ranked_type! { impl HintKnown { - impl['a] type T['a] for ValueKnown = - ValueKnown; + impl['a, 'ctx, T] type T['a, 'ctx] for ValueKnownHrt<T> = + ValueKnown<'a, TypeName::T<'a, 'ctx, T>> + where { + T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>, + }; - impl['a] type HigherRanked['a] for ValueKnown = - ValueKnown; + impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for ValueKnown<'a, T> = + ValueKnownHrt<<T as TypeName::RaiseForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>>::HigherRanked> + where { + T: ?Sized + TypeName::LowerType<'a, 'ctx>, + }; } } // This enrolls the Value protocol into the walker hint system. -impl<'a, 'ctx: 'a, T: TypeName::MemberType, E: Effect> HintMeta<'ctx> for ValueProto<T, E> { - type Known = ValueKnown; +impl<T: TypeName::MemberType, E: Effect> HintMeta for ValueProto<T, E> { + type Known = ValueKnownHrt<T>; type Hint = (); } @@ -72,12 +94,11 @@ impl<'a, 'ctx: 'a, T: TypeName::MemberType, E: Effect> HintMeta<'ctx> for ValueP pub fn visit_value<'a, 'ctx, T: Send + TypeName::LowerType<'a, 'ctx>, E: Effect>( visitor: Visitor<'a, 'ctx>, value: T, -) -> Future<'a, VisitResult<T>, E> +) -> Future<'a, VisitResult<T>, E> where - TypeName::HigherRanked<'a, 'ctx, T>: TypeName::MemberType + TypeName::HigherRanked<'a, 'ctx, T>: TypeName::MemberType, { - if let Some(object) = - visitor.upcast_mut::<ValueProto<TypeName::HigherRanked<'a, 'ctx, T>, E>>() + if let Some(object) = visitor.upcast_mut::<ValueProto<TypeName::HigherRanked<'a, 'ctx, T>, E>>() { // Allow the visitor to give a hint if it wants. object.visit(value) |