Diffstat (limited to 'src/protocol/walker/hint.rs')
| -rw-r--r-- | src/protocol/walker/hint.rs | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs index 8707923..148b8f2 100644 --- a/src/protocol/walker/hint.rs +++ b/src/protocol/walker/hint.rs @@ -5,11 +5,11 @@ //! to the walker about what it is expecting. use crate::{ - any::TypeName, - effect::{Effect, ErasedEffective}, + any::{AnyTrait, TypeName}, + effect::{Effect, EffectiveExt as _, ErasedEffective, ReadyExt as _, Ss}, higher_ranked_trait, higher_ranked_type, hkt::Marker, - protocol::DynVisitor, + protocol::{visitor::VisitResult, DynVisitor, DynWalker}, Flow, }; @@ -54,11 +54,13 @@ pub trait Hint<'ctx, Protocol: ?Sized + HintMeta> { /// Hint to the walker to use the `P` protocol. /// /// This should only be called once per [`RequestHint`]. - fn hint<'a>( - &'a mut self, - visitor: DynVisitor<'a, 'ctx>, - hint: MetaHint<'a, 'ctx, Protocol>, - ) -> ErasedEffective<'a, Flow, Protocol::Effect>; + fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( + &'this mut self, + visitor: DynVisitor<'visitor, 'ctx>, + hint: MetaHint<'hint, 'ctx, Protocol>, + ) -> ErasedEffective<'e, Flow, Protocol::Effect> + where + 'ctx: 'this + 'visitor + 'hint + 'e; /// Ask the walker for information about it's support of the protocol. fn known<'a>( @@ -74,13 +76,33 @@ higher_ranked_type! { impl['a, 'ctx, Protocol] type T['a, 'ctx] for HintProto<Protocol> = dyn Hint<'ctx, Protocol> + Send + Sync + 'a where { - Protocol: 'static, + Protocol: ?Sized + 'static, }; impl['a, 'ctx, Protocol] type HigherRanked['a, 'ctx] for dyn Hint<'ctx, Protocol> + Send + Sync + 'a = HintProto<Protocol> where { - Protocol: 'static, + Protocol: ?Sized + 'static, }; } } + +pub fn hint_protocol< + 'ctx, + 'walker: 'e, + 'visitor: 'e, + 'hint: 'e, + 'e, + Protocol: ?Sized + HintMeta, + V: AnyTrait<'ctx> + Ss, +>( + walker: DynWalker<'walker, 'ctx>, + visitor: &'visitor mut V, + hint: MetaHint<'hint, 'ctx, Protocol>, +) -> ErasedEffective<'e, VisitResult<()>, Protocol::Effect> { + if let Some(object) = walker.0.upcast_mut::<HintProto<Protocol>>() { + object.hint(DynVisitor(visitor), hint).map(Into::into) + } else { + VisitResult::Skipped(()).ready() + } +} |