Diffstat (limited to 'src/impls/core/reference.rs')
| -rw-r--r-- | src/impls/core/reference.rs | 139 |
1 files changed, 104 insertions, 35 deletions
diff --git a/src/impls/core/reference.rs b/src/impls/core/reference.rs index 4016a26..0f5038d 100644 --- a/src/impls/core/reference.rs +++ b/src/impls/core/reference.rs @@ -1,15 +1,19 @@ use core::any::Any; use crate::{ - protocol::{lookup_visit, VisitorMissingProtocol, WalkerMissingProtocol, lookup_hint, ProtocolId, AnyVisit, Visit}, - protocols::reference, - walk::{WalkMut, WalkOnce, Walk}, - Visitor, Walker, ControlFlow, build::{Builder, Build}, + build::{Build, Builder}, + protocol::{ + lookup_hint, lookup_visit, AnyHint, AnyVisit, Hint, ProtocolId, Visit, + VisitorMissingProtocol, WalkerMissingProtocol, + }, + protocols::{recoverable, reference}, + walk::{Walk, WalkMut, WalkOnce}, + ControlFlow, Visitor, Walker, }; impl<'borrow, 'ctx, T> WalkOnce<'ctx> for &'borrow T where - T: Walk<'borrow, 'ctx> + T: Walk<'borrow, 'ctx>, { type Error = T::Error; @@ -20,18 +24,21 @@ where } } -impl<'borrow, 'a, 'ctx, T> WalkMut<'borrow, 'ctx> for &'a T -where - T: Walk<'a, 'ctx> +impl<'borrow, 'a, 'ctx, T> WalkMut<'borrow, 'ctx> for &'a T +where + T: Walk<'a, 'ctx>, { - fn walk_mut(&'borrow mut self, visitor: &mut dyn Visitor<'ctx>) -> Result<Self::Value, Self::Error> { + fn walk_mut( + &'borrow mut self, + visitor: &mut dyn Visitor<'ctx>, + ) -> Result<Self::Value, Self::Error> { T::walk(self, visitor) } } -impl<'borrow, 'a, 'ctx, T> Walk<'borrow, 'ctx> for &'a T +impl<'borrow, 'a, 'ctx, T> Walk<'borrow, 'ctx> for &'a T where - T: Walk<'a, 'ctx> + T: Walk<'a, 'ctx>, { fn walk(&'borrow self, visitor: &mut dyn Visitor<'ctx>) -> Result<Self::Value, Self::Error> { T::walk(self, visitor) @@ -49,27 +56,88 @@ pub struct RefWalker<'ctx, T: ?Sized> { impl<'ctx, T: ?Sized> RefWalker<'ctx, T> { pub fn new(value: &'ctx T) -> Self { - Self { - value, - error: None, + Self { value, error: None } + } +} + +impl<'ctx, T: ?Sized + Any> WalkOnce<'ctx> for RefWalker<'ctx, T> { + type Error = VisitorMissingProtocol; + + type Value = (); + + fn walk_once(mut self, visitor: &mut dyn Visitor<'ctx>) -> Result<Self::Value, Self::Error> { + match visitor.request_hint(&mut self, false) { + ControlFlow::Continue => { + Hint::<reference::Reference<T>>::hint( + &mut self, + visitor, + reference::Hint { + kind: None, + min_len: None, + max_len: None, + }, + ); + } + _ => {} + } + + if let Some(err) = self.error { + Err(err) + } else { + Ok(()) } } +} - pub fn into_error(self) -> Option<VisitorMissingProtocol> { - self.error +impl<'ctx, T: ?Sized + Any> Walker<'ctx> for RefWalker<'ctx, T> { + fn protocol(&mut self, id: ProtocolId) -> Option<crate::protocol::AnyHint<'_, 'ctx>> { + if id == ProtocolId::of::<reference::Reference<T>>() { + Some(AnyHint::new::<reference::Reference<T>>(self)) + } else if id == ProtocolId::of::<reference::Reference<T>>() { + Some(AnyHint::new::<recoverable::Recoverable>(self)) + } else { + None + } } } -impl<'ctx:, T: ?Sized + Any> Walker<'ctx> for RefWalker<'ctx, T> { - fn walk(&mut self, visitor: &mut dyn Visitor<'ctx>) -> ControlFlow { +impl<'ctx, T: ?Sized + Any> Hint<'ctx, reference::Reference<T>> for RefWalker<'ctx, T> { + fn hint(&mut self, visitor: &mut dyn Visitor<'ctx>, _hint: reference::Hint) -> ControlFlow { match lookup_visit::<reference::Reference<T>, _>(visitor) { Ok(visit) => visit.visit(reference::Ref::Context(self.value)).to_done(), Err(err) => { self.error = Some(err); ControlFlow::Error - }, + } + } + } + + fn known(&mut self, _hint: &reference::Hint) -> reference::Known { + reference::Known { + kind: Some(reference::Kind::Context), + len: None, + } + } +} + +impl<'ctx, T: ?Sized + Any> Hint<'ctx, recoverable::Recoverable> for RefWalker<'ctx, T> { + fn hint(&mut self, visitor: &mut dyn Visitor<'ctx>, _hint: ()) -> ControlFlow { + match lookup_visit::<recoverable::Recoverable, _>(visitor) { + Ok(visit) => visit.visit(self).to_done(), + Err(err) => { + self.error = Some(err); + ControlFlow::Error + } } } + + fn known(&mut self, _hint: &()) {} +} + +impl<'ctx, T: ?Sized + Any> recoverable::Accessor<'ctx> for RefWalker<'ctx, T> { + fn new_walk(&mut self, visitor: &mut dyn Visitor<'ctx>) -> ControlFlow { + todo!() + } } #[derive(thiserror::Error, Debug)] @@ -81,7 +149,7 @@ pub enum Error { ShortLifetime, #[error(transparent)] - MissingProtocol(#[from] WalkerMissingProtocol) + MissingProtocol(#[from] WalkerMissingProtocol), } pub struct RefBuilder<'ctx, T: ?Sized> { @@ -115,19 +183,22 @@ impl<'ctx, T: ?Sized + Any> Builder<'ctx> for RefBuilder<'ctx, T> { impl<'ctx, T: ?Sized + Any> Visitor<'ctx> for RefBuilder<'ctx, T> { fn request_hint( &mut self, - hints: &mut dyn crate::WalkerHints<'ctx>, + hints: &mut dyn crate::Walker<'ctx>, _need_hint: bool, ) -> ControlFlow { match lookup_hint::<reference::Reference<T>, _>(hints) { - Ok(hint) => hint.hint(self, reference::Hint { - kind: Some(reference::Kind::Context), - min_len: None, - max_len: None, - }), + Ok(hint) => hint.hint( + self, + reference::Hint { + kind: Some(reference::Kind::Context), + min_len: None, + max_len: None, + }, + ), Err(err) => { self.value = Some(Err(err.into())); ControlFlow::Error - }, + } } } @@ -148,12 +219,11 @@ impl<'ctx, T: ?Sized + Any> Visit<'ctx, reference::Reference<T>> for RefBuilder< reference::Ref::Walking(_) => { self.value = Some(Err(Error::ShortLifetime)); ControlFlow::Error - }, - reference::Ref::Context(value) | - reference::Ref::Static(value) => { + } + reference::Ref::Context(value) | reference::Ref::Static(value) => { self.value = Some(Ok(value)); ControlFlow::Done - }, + } } } } @@ -164,12 +234,11 @@ impl<'ctx, T: ?Sized + Any> Visit<'ctx, reference::ReferenceMut<T>> for RefBuild reference::Mut::Walking(_) => { self.value = Some(Err(Error::ShortLifetime)); ControlFlow::Error - }, - reference::Mut::Context(value) | - reference::Mut::Static(value) => { + } + reference::Mut::Context(value) | reference::Mut::Static(value) => { self.value = Some(Ok(value)); ControlFlow::Done - }, + } } } } |