Diffstat (limited to 'src/protocol/walker/hint.rs')
-rw-r--r--src/protocol/walker/hint.rs42
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()
+ }
+}