Diffstat (limited to 'src/impls/core/reference.rs')
-rw-r--r--src/impls/core/reference.rs429
1 files changed, 107 insertions, 322 deletions
diff --git a/src/impls/core/reference.rs b/src/impls/core/reference.rs
index 69c8f08..4016a26 100644
--- a/src/impls/core/reference.rs
+++ b/src/impls/core/reference.rs
@@ -1,390 +1,175 @@
-use core::{any::Any, marker::PhantomData};
+use core::any::Any;
use crate::{
- build::{Build, Builder},
- error::{Missing, PrimitiveTypeError, UniError},
- protocol::{lookup_visit, AnyProtocolVisit, AnyVisit, ProtocolDescription, ProtocolId, Visit},
+ protocol::{lookup_visit, VisitorMissingProtocol, WalkerMissingProtocol, lookup_hint, ProtocolId, AnyVisit, Visit},
protocols::reference,
- walk::{Walk, WalkMut, WalkOnce},
- Fallible, Visitor, WalkStatus, Walker,
+ walk::{WalkMut, WalkOnce, Walk},
+ Visitor, Walker, ControlFlow, build::{Builder, Build},
};
-pub trait LifetimeBound {}
-
-pub enum ValueLifetime {}
-pub enum ContextLifetime {}
-pub enum StaticLifetime {}
-
-impl LifetimeBound for ValueLifetime {}
-impl LifetimeBound for ContextLifetime {}
-impl LifetimeBound for StaticLifetime {}
-
-pub struct RefWalker<'a, T: ?Sized, Lt: LifetimeBound>(&'a T, PhantomData<Lt>);
-
-impl<'a, T: ?Sized, Lt: LifetimeBound> RefWalker<'a, T, Lt> {
- pub fn new(value: &'a T) -> Self {
- Self(value, PhantomData)
- }
-}
-
-impl<'ctx, T: ?Sized, Lt: LifetimeBound> Fallible for RefWalker<'ctx, T, Lt> {
- type Error = PrimitiveTypeError;
-}
-
-impl<'value, 'borrow: 'value, 'ctx: 'borrow, T: ?Sized + Any, VisitorErr: 'value>
- Walker<'value, 'ctx, VisitorErr> for RefWalker<'borrow, T, ValueLifetime>
-{
- fn walk(
- &mut self,
- visitor: &mut dyn Visitor<'value, 'ctx, Self::Error, Error = VisitorErr>,
- ) -> Result<WalkStatus, UniError<Self::Error, VisitorErr>> {
- let mut protocol =
- lookup_visit::<reference::Reference<T>, _, _>(visitor).map_err(UniError::Walker)?;
-
- protocol.visit(reference::Ref::Value(self.0))?;
-
- Ok(WalkStatus::Repeat)
- }
-}
-
-impl<'value, 'ctx: 'value, 'borrow: 'ctx, T: ?Sized + Any, VisitorErr: 'value>
- Walker<'value, 'ctx, VisitorErr> for RefWalker<'borrow, T, ContextLifetime>
-{
- fn walk(
- &mut self,
- visitor: &mut dyn Visitor<'value, 'ctx, Self::Error, Error = VisitorErr>,
- ) -> Result<WalkStatus, UniError<Self::Error, VisitorErr>> {
- let mut protocol =
- lookup_visit::<reference::Reference<T>, _, _>(visitor).map_err(UniError::Walker)?;
-
- protocol.visit(reference::Ref::Context(self.0))?;
-
- Ok(WalkStatus::Repeat)
- }
-}
-
-impl<'value, 'ctx: 'value, 'borrow: 'ctx, T: ?Sized + Any, VisitorErr: 'value>
- Walker<'value, 'ctx, VisitorErr> for RefWalker<'static, T, StaticLifetime>
-{
- fn walk(
- &mut self,
- visitor: &mut dyn Visitor<'value, 'ctx, Self::Error, Error = VisitorErr>,
- ) -> Result<WalkStatus, UniError<Self::Error, VisitorErr>> {
- let mut protocol =
- lookup_visit::<reference::Reference<T>, _, _>(visitor).map_err(UniError::Walker)?;
-
- protocol.visit(reference::Ref::Static(self.0))?;
-
- Ok(WalkStatus::Repeat)
- }
-}
-
-impl<'value, 'borrow: 'value, 'ctx: 'borrow, T: ?Sized> WalkOnce<'value, 'ctx> for &'borrow T
+impl<'borrow, 'ctx, T> WalkOnce<'ctx> for &'borrow T
where
- T: Walk<'value, 'borrow, 'ctx>,
+ T: Walk<'borrow, 'ctx>
{
type Error = T::Error;
- type Walker<VisitorErr: 'value> = T::Walker<VisitorErr>;
+ type Value = T::Value;
- fn into_walker<VisitorErr: 'value>(self) -> Self::Walker<VisitorErr> {
- T::walker(self)
+ fn walk_once(self, visitor: &mut dyn Visitor<'ctx>) -> Result<Self::Value, Self::Error> {
+ T::walk(self, visitor)
}
}
-impl<'value, 'method: 'value, 'borrow: 'method, 'ctx: 'borrow, T: ?Sized>
- WalkMut<'value, 'method, 'ctx> for &'borrow T
-where
- T: Walk<'value, 'borrow, 'ctx>,
+impl<'borrow, 'a, 'ctx, T> WalkMut<'borrow, 'ctx> for &'a T
+where
+ T: Walk<'a, 'ctx>
{
- type Error = T::Error;
-
- type Walker<VisitorErr: 'value> = T::Walker<VisitorErr>;
-
- fn walker_mut<VisitorErr: 'value>(&'method mut self) -> Self::Walker<VisitorErr> {
- T::walker(self)
+ fn walk_mut(&'borrow mut self, visitor: &mut dyn Visitor<'ctx>) -> Result<Self::Value, Self::Error> {
+ T::walk(self, visitor)
}
}
-impl<'value, 'method: 'value, 'borrow: 'method, 'ctx: 'borrow, T: ?Sized>
- Walk<'value, 'method, 'ctx> for &'borrow T
+impl<'borrow, 'a, 'ctx, T> Walk<'borrow, 'ctx> for &'a T
where
- T: Walk<'value, 'borrow, 'ctx>,
+ T: Walk<'a, 'ctx>
{
- type Error = T::Error;
-
- type Walker<VisitorErr: 'value> = T::Walker<VisitorErr>;
-
- fn walker<VisitorErr: 'value>(&'method self) -> Self::Walker<VisitorErr> {
- T::walker(self)
+ fn walk(&'borrow self, visitor: &mut dyn Visitor<'ctx>) -> Result<Self::Value, Self::Error> {
+ T::walk(self, visitor)
}
}
-impl<'value, 'borrow: 'value, 'ctx: 'borrow, T: ?Sized> WalkOnce<'value, 'ctx> for &'borrow mut T
-where
- T: WalkMut<'value, 'borrow, 'ctx>,
-{
- type Error = T::Error;
-
- type Walker<VisitorErr: 'value> = T::Walker<VisitorErr>;
-
- fn into_walker<VisitorErr: 'value>(self) -> Self::Walker<VisitorErr> {
- T::walker_mut(self)
- }
+impl<'ctx, T: ?Sized + Any> Build<'ctx> for &'ctx T {
+ type Builder = RefBuilder<'ctx, T>;
}
-impl<'value, 'borrow: 'value, 'ctx: 'borrow, T: ?Sized> WalkMut<'value, 'borrow, 'ctx>
- for &'borrow mut T
-where
- T: WalkMut<'value, 'borrow, 'ctx>,
-{
- type Error = T::Error;
-
- type Walker<VisitorErr: 'value> = T::Walker<VisitorErr>;
-
- fn walker_mut<VisitorErr: 'value>(&'borrow mut self) -> Self::Walker<VisitorErr> {
- T::walker_mut(self)
- }
+pub struct RefWalker<'ctx, T: ?Sized> {
+ value: &'ctx T,
+ error: Option<VisitorMissingProtocol>,
}
-#[derive(thiserror::Error, Debug)]
-pub enum LifetimeIsShort<'value, 'ctx, T: ?Sized> {
- Walking,
- Value(&'value T),
- Context(&'ctx T),
-}
-
-pub struct RefBuilder<'value, T: ?Sized, Lt: LifetimeBound>(Option<&'value T>, PhantomData<Lt>);
-
-impl<'value, 'ctx: 'value, T: ?Sized + Any> Builder<'value, 'ctx>
- for RefBuilder<'value, T, ValueLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
-
- type Value = &'value T;
-
- fn init() -> Self
- where
- Self: Sized,
- {
- Self(None, PhantomData)
+impl<'ctx, T: ?Sized> RefWalker<'ctx, T> {
+ pub fn new(value: &'ctx T) -> Self {
+ Self {
+ value,
+ error: None,
+ }
}
- fn as_visitor<WalkerErr: 'value>(
- &mut self,
- ) -> &mut dyn Visitor<'value, 'ctx, WalkerErr, Error = Self::Error> {
- self
+ pub fn into_error(self) -> Option<VisitorMissingProtocol> {
+ self.error
}
+}
- fn finish(self) -> Result<Self::Value, Self::Error>
- where
- Self: Sized,
- {
- if let Some(value) = self.0 {
- Ok(value)
- } else {
- Err(Missing::Missing)
+impl<'ctx:, T: ?Sized + Any> Walker<'ctx> for RefWalker<'ctx, T> {
+ fn walk(&mut self, visitor: &mut dyn Visitor<'ctx>) -> 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
+ },
}
}
}
-impl<'value, 'ctx: 'value, T: ?Sized + Any, WalkerErr: 'value> Visitor<'value, 'ctx, WalkerErr>
- for RefBuilder<'value, T, ValueLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+ #[error("Missing value after walk.")]
+ MissingValue,
- fn protocol(
- &mut self,
- id: ProtocolId,
- ) -> Option<AnyProtocolVisit<'_, 'value, 'ctx, WalkerErr, Self::Error>> {
- match id {
- id if id == ProtocolId::of::<reference::Reference<T>>() => {
- Some(AnyVisit::new(self).erase())
- }
- _ => None,
- }
- }
+ #[error("A value with a lifetime to short was given.")]
+ ShortLifetime,
+
+ #[error(transparent)]
+ MissingProtocol(#[from] WalkerMissingProtocol)
}
-impl<'value, 'ctx: 'value, T: ?Sized + Any, WalkerErr>
- Visit<'value, 'ctx, reference::Reference<T>, WalkerErr>
- for RefBuilder<'value, T, ValueLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
+pub struct RefBuilder<'ctx, T: ?Sized> {
+ value: Option<Result<&'ctx T, Error>>,
+}
- fn visit<'walking>(
- &'walking mut self,
- accessor: reference::Ref<'walking, 'value, 'ctx, T>,
- ) -> Result<(), UniError<WalkerErr, Self::Error>> {
- match accessor {
- reference::Ref::Walking(_) => {
- Err(UniError::Visitor(Missing::Error(LifetimeIsShort::Walking)))
- }
- reference::Ref::Value(value)
- | reference::Ref::Context(value)
- | reference::Ref::Static(value) => {
- self.0 = Some(value);
- Ok(())
- }
- }
+impl<'ctx, T: ?Sized> Default for RefBuilder<'ctx, T> {
+ fn default() -> Self {
+ Self { value: None }
}
}
-impl<'value, 'ctx: 'value, T: ?Sized + Any> Builder<'value, 'ctx>
- for RefBuilder<'ctx, T, ContextLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
+impl<'ctx, T: ?Sized + Any> Builder<'ctx> for RefBuilder<'ctx, T> {
+ type Error = Error;
type Value = &'ctx T;
- fn init() -> Self
- where
- Self: Sized,
- {
- Self(None, PhantomData)
- }
-
- fn as_visitor<WalkerErr: 'value>(
- &mut self,
- ) -> &mut dyn Visitor<'value, 'ctx, WalkerErr, Error = Self::Error> {
+ fn as_visitor(&mut self) -> &mut dyn Visitor<'ctx> {
self
}
- fn finish(self) -> Result<Self::Value, Self::Error>
- where
- Self: Sized,
- {
- if let Some(value) = self.0 {
- Ok(value)
- } else {
- Err(Missing::Missing)
+ fn build(self) -> Result<Self::Value, Self::Error> {
+ match self.value {
+ Some(Ok(value)) => Ok(value),
+ Some(Err(err)) => Err(err.into()),
+ None => Err(Error::MissingValue),
}
}
}
-impl<'value, 'ctx: 'value, T: ?Sized + Any, WalkerErr: 'value> Visitor<'value, 'ctx, WalkerErr>
- for RefBuilder<'ctx, T, ContextLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
-
- fn protocol(
+impl<'ctx, T: ?Sized + Any> Visitor<'ctx> for RefBuilder<'ctx, T> {
+ fn request_hint(
&mut self,
- id: ProtocolId,
- ) -> Option<AnyProtocolVisit<'_, 'value, 'ctx, WalkerErr, Self::Error>> {
- match id {
- id if id == ProtocolId::of::<reference::Reference<T>>() => {
- Some(AnyVisit::new(self).erase())
- }
- _ => None,
+ hints: &mut dyn crate::WalkerHints<'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,
+ }),
+ Err(err) => {
+ self.value = Some(Err(err.into()));
+ ControlFlow::Error
+ },
}
}
-}
-impl<'value, 'ctx: 'value, T: ?Sized + Any, WalkerErr>
- Visit<'value, 'ctx, reference::Reference<T>, WalkerErr>
- for RefBuilder<'ctx, T, ContextLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
-
- fn visit<'walking>(
- &'walking mut self,
- accessor: reference::Ref<'walking, 'value, 'ctx, T>,
- ) -> Result<(), UniError<WalkerErr, Self::Error>> {
- match accessor {
- reference::Ref::Walking(_) => {
- Err(UniError::Visitor(Missing::Error(LifetimeIsShort::Walking)))
- }
- reference::Ref::Value(value) => Err(UniError::Visitor(Missing::Error(
- LifetimeIsShort::Value(value),
- ))),
- reference::Ref::Context(value) | reference::Ref::Static(value) => {
- self.0 = Some(value);
- Ok(())
- }
- }
- }
-}
-
-impl<'value, 'ctx: 'value, T: ?Sized + Any> Builder<'value, 'ctx>
- for RefBuilder<'static, T, StaticLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
-
- type Value = &'static T;
-
- fn init() -> Self
- where
- Self: Sized,
- {
- Self(None, PhantomData)
- }
-
- fn as_visitor<WalkerErr: 'value>(
- &mut self,
- ) -> &mut dyn Visitor<'value, 'ctx, WalkerErr, Error = Self::Error> {
- self
- }
-
- fn finish(self) -> Result<Self::Value, Self::Error>
- where
- Self: Sized,
- {
- if let Some(value) = self.0 {
- Ok(value)
+ fn protocol(&mut self, id: crate::protocol::ProtocolId) -> Option<AnyVisit<'_, 'ctx>> {
+ if id == ProtocolId::of::<reference::Reference<T>>() {
+ Some(AnyVisit::new::<reference::Reference<T>>(self))
+ } else if id == ProtocolId::of::<reference::ReferenceMut<T>>() {
+ Some(AnyVisit::new::<reference::ReferenceMut<T>>(self))
} else {
- Err(Missing::Missing)
+ None
}
}
}
-impl<'value, 'ctx: 'value, T: ?Sized + Any, WalkerErr: 'value> Visitor<'value, 'ctx, WalkerErr>
- for RefBuilder<'static, T, StaticLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
-
- fn protocol(
- &mut self,
- id: ProtocolId,
- ) -> Option<AnyProtocolVisit<'_, 'value, 'ctx, WalkerErr, Self::Error>> {
- match id {
- id if id == ProtocolId::of::<reference::Reference<T>>() => {
- Some(AnyVisit::new(self).erase())
- }
- _ => None,
- }
- }
-}
-
-impl<'value, 'ctx: 'value, T: ?Sized + Any, WalkerErr>
- Visit<'value, 'ctx, reference::Reference<T>, WalkerErr>
- for RefBuilder<'static, T, StaticLifetime>
-{
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
-
- fn visit<'walking>(
- &'walking mut self,
- accessor: reference::Ref<'walking, 'value, 'ctx, T>,
- ) -> Result<(), UniError<WalkerErr, Self::Error>> {
+impl<'ctx, T: ?Sized + Any> Visit<'ctx, reference::Reference<T>> for RefBuilder<'ctx, T> {
+ fn visit(&mut self, accessor: reference::Ref<'_, 'ctx, T>) -> ControlFlow {
match accessor {
reference::Ref::Walking(_) => {
- Err(UniError::Visitor(Missing::Error(LifetimeIsShort::Walking)))
- }
- reference::Ref::Value(value) => Err(UniError::Visitor(Missing::Error(
- LifetimeIsShort::Value(value),
- ))),
- reference::Ref::Context(value) => Err(UniError::Visitor(Missing::Error(
- LifetimeIsShort::Context(value),
- ))),
+ self.value = Some(Err(Error::ShortLifetime));
+ ControlFlow::Error
+ },
+ reference::Ref::Context(value) |
reference::Ref::Static(value) => {
- self.0 = Some(value);
- Ok(())
- }
+ self.value = Some(Ok(value));
+ ControlFlow::Done
+ },
}
}
}
-impl<'value, 'ctx: 'value, T: ?Sized + Any> Build<'value, 'ctx> for &'value T {
- type Error = Missing<LifetimeIsShort<'value, 'ctx, T>>;
-
- type Builder = RefBuilder<'value, T, ValueLifetime>;
+impl<'ctx, T: ?Sized + Any> Visit<'ctx, reference::ReferenceMut<T>> for RefBuilder<'ctx, T> {
+ fn visit(&mut self, accessor: reference::Mut<'_, 'ctx, T>) -> ControlFlow {
+ match accessor {
+ reference::Mut::Walking(_) => {
+ self.value = Some(Err(Error::ShortLifetime));
+ ControlFlow::Error
+ },
+ reference::Mut::Context(value) |
+ reference::Mut::Static(value) => {
+ self.value = Some(Ok(value));
+ ControlFlow::Done
+ },
+ }
+ }
}