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