Diffstat (limited to 'src/walk.rs')
| -rw-r--r-- | src/walk.rs | 67 |
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() +} |