Diffstat (limited to 'src/impls/core/str.rs')
-rw-r--r--src/impls/core/str.rs112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/impls/core/str.rs b/src/impls/core/str.rs
new file mode 100644
index 0000000..a3fcc01
--- /dev/null
+++ b/src/impls/core/str.rs
@@ -0,0 +1,112 @@
+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, 'ctx: 'value>(&'value str, PhantomData<&'ctx ()>);
+
+impl<'value, 'ctx: 'value, VisitorErr: 'ctx> crate::Walker<'value, 'ctx, VisitorErr>
+ for Walker<'value, 'ctx>
+{
+ 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, 'ctx: 'value, VisitorErr: 'ctx> WalkerHints<'value, 'ctx, VisitorErr>
+ for Walker<'value, 'ctx>
+{
+ 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, 'ctx: 'value, VisitorErr: 'ctx> Hint<'value, 'ctx, Reference<str>, VisitorErr>
+ for Walker<'value, 'ctx>
+{
+ 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, 'ctx: 'value, VisitorErr: 'ctx> Walk<'value, 'ctx, VisitorErr> for str {
+ type Error = BasicError;
+ type Walker = Walker<'value, 'ctx>;
+
+ fn walker(&'value self) -> Self::Walker {
+ Walker(self, PhantomData)
+ }
+}