use core::marker::PhantomData;
use crate::{
build::{Build, Builder},
error::{BasicError, UniError},
protocol::{
lookup_hint, lookup_visit, AnyHint, AnyVisit, Hint, Protocol, ProtocolDescription,
ProtocolId,
},
protocol_list,
protocols::reference::{self, Reference},
walk::{Walk, WalkMut, WalkOnce},
walk_with_hints, HintGiven, WalkerHints,
};
use super::reference::BuilderRefValue;
pub struct Walker<'value>(&'value str);
impl<'value, 'borrow: 'value, 'ctx: 'borrow, VisitorErr: 'value> crate::Walker<'value, 'ctx, VisitorErr>
for Walker<'borrow>
{
type Error = BasicError;
fn walk(
&mut self,
visitor: &mut dyn crate::Visitor<'value, 'ctx, Self::Error, Error = VisitorErr>,
) -> Result<crate::WalkStatus, UniError<Self::Error, VisitorErr>> {
match lookup_visit::<Reference<str>, _, _>(visitor).map_err(UniError::Walker)? {
Some(visitor) => {
visitor.visit(reference::Ref::Value(self.0))?;
Ok(crate::WalkStatus::Continue)
}
None => Err(UniError::Walker(BasicError::new(
"visitor needs the reference protocol for `str`",
))),
}
}
fn all_protocols() -> impl Iterator<Item = ProtocolDescription>
where
Self: Sized,
{
protocol_list![Reference<str>]
}
}
impl<'value, 'borrow: 'value, 'ctx: 'borrow, VisitorErr: 'value> WalkerHints<'value, 'ctx, VisitorErr>
for Walker<'borrow>
{
type Error = BasicError;
fn protocol(
&mut self,
id: ProtocolId,
) -> Option<AnyHint<'_, 'value, 'ctx, Self::Error, VisitorErr>> {
match id {
id if id == ProtocolId::of::<Reference<str>>() => Some(AnyHint::new(self)),
_ => None,
}
}
}
impl<'value, 'borrow: 'value, 'ctx: 'borrow, VisitorErr: 'value> Hint<'value, 'ctx, Reference<str>, VisitorErr>
for Walker<'borrow>
{
type Error = BasicError;
fn hint(
&mut self,
visitor: &mut dyn crate::Visitor<'value, 'ctx, Self::Error, Error = VisitorErr>,
_hint: <Reference<str> as crate::protocol::Protocol<'value, 'ctx>>::Hint,
) -> Result<HintGiven, UniError<Self::Error, VisitorErr>> {
lookup_visit::<Reference<str>, _, _>(visitor)
.map_err(UniError::Walker)?
.ok_or_else(|| {
UniError::Walker(BasicError::new("visitor is missing the str protocol"))
})?
.visit(reference::Ref::Value(self.0))?;
Ok(HintGiven)
}
fn known(
&mut self,
_hint: &<Reference<str> as crate::protocol::Protocol<'value, 'ctx>>::Hint,
) -> Result<<Reference<str> as crate::protocol::Protocol<'value, 'ctx>>::Known, BasicError>
{
Ok(reference::Known {
len: Some(self.0.len()),
kind: Some(reference::Kind::Context),
})
}
}
// impl<'value, 'ctx: 'value, VisitorErr: 'ctx> WalkMut<'value, 'ctx, VisitorErr> for str {
// type ErrorMut = BasicError;
// type WalkerMut = Walker<'value, 'ctx>;
//
// fn walker_mut(&'value mut self) -> Self::WalkerMut {
// Walker(self, PhantomData)
// }
// }
// impl<'value, 'borrow: 'value, 'ctx: 'borrow, VisitorErr: 'value> Walk<'value, 'borrow, 'ctx, VisitorErr> for str {
// type Error = BasicError;
// type Walker = Walker<'borrow>;
//
// fn walker(&'borrow self) -> Self::Walker {
// Walker(self)
// }
// }
impl<'value, 'borrow: 'value, 'ctx: 'borrow, VisitorErr: 'value> Walk<'value, 'borrow, 'ctx, VisitorErr> for str {
type Error = BasicError;
type Walker = Walker<'borrow>;
fn walker(&'borrow self) -> Self::Walker {
Walker(self)
}
}
//
// impl<'value, 'ctx: 'value, VisitorErr: 'value> Walk<'value, 'value, 'ctx, VisitorErr> for i32 {
// type Error = BasicError;
// type Walker = Walker<'value, 'ctx>;
//
// fn walker(&'value self) -> Self::Walker {
// // Walker(self, PhantomData)
// todo!()
// }
// }