Diffstat (limited to 'src/impls/core/reference.rs')
-rw-r--r--src/impls/core/reference.rs180
1 files changed, 151 insertions, 29 deletions
diff --git a/src/impls/core/reference.rs b/src/impls/core/reference.rs
index 457af7a..d1fe29e 100644
--- a/src/impls/core/reference.rs
+++ b/src/impls/core/reference.rs
@@ -21,40 +21,77 @@ use crate::{
walk::{Walk, WalkMut, WalkOnce},
};
-impl<'value, 'ctx: 'value, VisitorErr: 'ctx, T: ?Sized> WalkOnce<'value, 'ctx, VisitorErr>
- for &'ctx T
-where
- T: Walk<'value, 'ctx, VisitorErr>,
-{
- type ErrorOnce = T::Error;
- type WalkerOnce = T::Walker;
-
- fn into_walker(self) -> T::Walker {
- T::walker(self)
- }
-}
-
-impl<'value, 'ctx: 'value, VisitorErr: 'ctx, T: ?Sized> WalkMut<'value, 'ctx, VisitorErr>
- for &'ctx T
-where
- T: Walk<'value, 'ctx, VisitorErr>,
-{
- type ErrorMut = T::Error;
- type WalkerMut = T::Walker;
-
- fn walker_mut(&'value mut self) -> T::Walker {
- T::walker(*self)
- }
-}
-
-impl<'value, 'ctx: 'value, VisitorErr: 'ctx, T: ?Sized> Walk<'value, 'ctx, VisitorErr> for &'ctx T
+// impl<'value, 'ctx: 'value, VisitorErr: 'ctx, T: ?Sized> WalkOnce<'value, 'ctx, VisitorErr>
+// for &'ctx T
+// where
+// T: Walk<'value, 'ctx, VisitorErr>,
+// {
+// type ErrorOnce = T::Error;
+// type WalkerOnce = T::Walker;
+//
+// fn into_walker(self) -> T::Walker {
+// T::walker(self)
+// }
+// }
+//
+// impl<'value, 'ctx: 'value, VisitorErr: 'ctx, T: ?Sized> WalkMut<'value, 'ctx, VisitorErr>
+// for &'ctx T
+// where
+// T: Walk<'value, 'ctx, VisitorErr>,
+// {
+// type ErrorMut = T::Error;
+// type WalkerMut = T::Walker;
+//
+// fn walker_mut(&'value mut self) -> T::Walker {
+// T::walker(*self)
+// }
+// }
+
+// pub struct Error<'value, 'ctx, E>(E, PhantomData<&'value &'ctx ()>);
+//
+// impl<'value, 'ctx, E: WalkerError<'ctx, 'static>> WalkerError<'value, 'ctx> for Error<'value, 'ctx, E> {
+// fn wrong_visit<P: crate::protocol::Protocol<'value, 'ctx>>() -> Self {
+// todo!()
+// }
+//
+// fn needs_hint() -> Self {
+// todo!()
+// }
+// }
+//
+// pub struct Walker<'value, 'ctx, 'root, W>(W, PhantomData<&'value &'ctx &'root ()>);
+//
+// impl<'value, 'ctx: 'value, 'root: 'ctx, W: crate::Walker<'value, 'ctx, VisitorErr>, VisitorErr> crate::Walker<'value, 'ctx, VisitorErr> for Walker<'value, 'ctx, 'root, W>
+// {
+// type Error = Error<'value, 'ctx, 'root, W::Error>;
+//
+// fn walk(
+// &mut self,
+// visitor: &mut dyn crate::Visitor<'value, 'ctx, Self::Error, Error = VisitorErr>,
+// ) -> Result<crate::WalkStatus, UniError<Self::Error, VisitorErr>> {
+// todo!()
+// }
+//
+// fn all_protocols() -> impl Iterator<Item = crate::protocol::ProtocolDescription>
+// where
+// Self: Sized {
+// W::all_protocols()
+// }
+// }
+
+/// `'value` and `'ctx` form the bounds of the possible lifetimes.
+/// These are what the walker will actually work with.
+///
+/// `'value`` < `'borrow` < `'ctx`
+/// `'borrow` allows &'value &'borrow T to forward to T's &'borrow T
+impl<'value, 'method: 'value, 'borrow: 'method, 'ctx: 'borrow, VisitorErr, T: ?Sized> Walk<'value, 'method, 'ctx, VisitorErr> for &'borrow T
where
- T: Walk<'value, 'ctx, VisitorErr>,
+ T: Walk<'value, 'borrow, 'ctx, VisitorErr>,
{
type Error = T::Error;
type Walker = T::Walker;
- fn walker(&'value self) -> Self::Walker {
+ fn walker(&'method self) -> Self::Walker {
T::walker(self)
}
}
@@ -172,6 +209,91 @@ impl<'value, 'ctx: 'value, WalkerErr: 'value, T: ?Sized + Any>
}
}
+#[derive(Debug)]
+pub struct BuilderRefContext<'ctx, T: ?Sized>(Option<&'ctx T>);
+
+impl<'value, 'ctx: 'value, WalkerErr: 'value, T: ?Sized + Any> Builder<'value, 'ctx, WalkerErr>
+ for BuilderRefContext<'ctx, T>
+{
+ type Error = Missing<WrongProtocol<ShortLifetime>>;
+
+ type Value = &'ctx T;
+
+ fn init() -> Self
+ where
+ Self: Sized,
+ {
+ Self(None)
+ }
+
+ fn as_visitor(
+ &mut self,
+ ) -> &mut dyn crate::Visitor<'value, 'ctx, WalkerErr, Error = Self::Error> {
+ self
+ }
+
+ fn finish(self) -> Result<Self::Value, crate::error::UniError<WalkerErr, Self::Error>>
+ where
+ Self: Sized,
+ {
+ self.0.ok_or(UniError::Visitor(Missing::Missing))
+ }
+}
+
+impl<'value, 'ctx: 'value, WalkerErr: 'value, T: ?Sized + Any>
+ crate::Visitor<'value, 'ctx, WalkerErr> for BuilderRefContext<'ctx, T>
+{
+ type Error = Missing<WrongProtocol<ShortLifetime>>;
+
+ fn protocol(
+ &mut self,
+ id: crate::protocol::ProtocolId,
+ ) -> Option<crate::protocol::AnyVisit<'_, 'value, 'ctx, WalkerErr, Self::Error>> {
+ match id {
+ id if id == ProtocolId::of::<Reference<T>>() => Some(AnyVisit::new(self)),
+ _ => None,
+ }
+ }
+
+ fn all_protocols() -> impl Iterator<Item = crate::protocol::ProtocolDescription>
+ where
+ Self: Sized,
+ {
+ protocol_list![Reference<T>]
+ }
+}
+
+impl<'value, 'ctx: 'value, WalkerErr: 'value, T: ?Sized + Any>
+ Visit<'value, 'ctx, Reference<T>, WalkerErr> for BuilderRefContext<'ctx, T>
+{
+ type Error = Missing<WrongProtocol<ShortLifetime>>;
+
+ fn visit<'walking>(
+ &'walking mut self,
+ accessor: <Reference<T> as crate::protocol::Protocol<'value, 'ctx>>::Accessor<
+ 'walking,
+ WalkerErr,
+ Self::Error,
+ >,
+ ) -> Result<(), UniError<WalkerErr, Self::Error>> {
+ use reference::Ref::*;
+
+ match accessor {
+ Walking(_) => Err(UniError::Visitor(Missing::Error(WrongProtocol::Error(
+ ShortLifetime::Walking,
+ )))),
+ Value(_) => Err(UniError::Visitor(Missing::Error(WrongProtocol::Error(
+ ShortLifetime::Value,
+ )))),
+ Context(value) | Static(value) => {
+ self.0 = Some(value);
+
+ Ok(())
+ }
+ }
+ }
+}
+
// === &mut T ===
impl<'value, 'ctx: 'value, VisitorErr: 'ctx, T> WalkOnce<'value, 'ctx, VisitorErr> for &'ctx mut T