Diffstat (limited to 'src/walk.rs')
-rw-r--r--src/walk.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/walk.rs b/src/walk.rs
new file mode 100644
index 0000000..e73df28
--- /dev/null
+++ b/src/walk.rs
@@ -0,0 +1,67 @@
+use crate::{error::WalkerError, Walker};
+
+/// A type that can be walked once.
+///
+/// A walkable type has one canonical walker type, but other walkers
+/// can operate on the same walkable type. This trait gives the canonical
+/// walker for an owned instance of the value. The `'value` lifetime
+/// is the lifetime of the value itself.
+///
+/// [`WalkableOnce`], [`WalkableMut`], and [`Walkable`] form a family of traits
+/// similar to the [`FnOnce`], [`FnMut`], [`Fn`] family of traits.
+pub trait WalkOnce<'value, 'ctx: 'value, VisitorErr> {
+ /// Error the walker can return during the walk.
+ type ErrorOnce: WalkerError<'value, 'ctx>;
+
+ /// Walker over an instance of the type.
+ type WalkerOnce: Walker<'value, 'ctx, VisitorErr, Error = Self::ErrorOnce>;
+
+ /// Create a walker over a value of the type.
+ ///
+ /// Walking over the value is able to transfer ownership to the visitor.
+ fn into_walker(self) -> Self::WalkerOnce;
+}
+
+/// A type that can be walked using a mutable borrow.
+///
+/// This trait gives the canonical walker for a mutably borrowed
+/// instance of the value. The `'value` lifetime is the lifetime of
+/// the value itself. The `'walking` lifetime can be used by
+/// [`Self::ErrorMut`] to reference the value using the passed mutable borrow.
+///
+/// [`WalkableOnce`], [`WalkableMut`], and [`Walkable`] form a family of traits
+/// similar to the [`FnOnce`], [`FnMut`], [`Fn`] family of traits.
+pub trait WalkMut<'value, 'ctx: 'value, VisitorErr> {
+ /// Error the walker can return during the walk.
+ type ErrorMut: WalkerError<'value, 'ctx>;
+
+ /// Walker over an instance of the type.
+ type WalkerMut: Walker<'value, 'ctx, VisitorErr, Error = Self::ErrorMut>;
+
+ fn walker_mut(&'value mut self) -> Self::WalkerMut;
+}
+
+pub trait Walk<'value, 'ctx: 'value, VisitorErr>: WalkMut<'value, 'ctx, VisitorErr> {
+ type Error: WalkerError<'value, 'ctx>;
+ type Walker: Walker<'value, 'ctx, VisitorErr, Error = Self::Error>;
+
+ fn walker(&'value self) -> Self::Walker;
+}
+
+pub fn walker_once<'value, 'ctx: 'value, VisitorErr, W: WalkOnce<'value, 'ctx, VisitorErr>>(
+ value: W,
+) -> W::WalkerOnce {
+ value.into_walker()
+}
+
+pub fn walker_mut<'value, 'ctx: 'value, VisitorErr, W: WalkMut<'value, 'ctx, VisitorErr>>(
+ value: &'value mut W,
+) -> W::WalkerMut {
+ value.walker_mut()
+}
+
+pub fn walker<'value, 'ctx: 'value, VisitorErr, W: Walk<'value, 'ctx, VisitorErr>>(
+ value: &'value W,
+) -> W::Walker {
+ value.walker()
+}