Diffstat (limited to 'src/impls/core/reference.rs')
-rw-r--r--src/impls/core/reference.rs139
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
- },
+ }
}
}
}