pub mod walkers;
use crate::{
effect::{Effect, Yield},
protocol::Visitor,
};
/// A type that can be walked.
pub trait Walk<'ctx>: Sized {
/// The walker for the type.
type Walker: Walker<'ctx> + From<Self>;
}
pub fn into_walker<'ctx, T: Walk<'ctx>>(value: T) -> T::Walker {
<T as Walk<'ctx>>::Walker::from(value)
}
/// Walker for a type.
///
/// The `'ctx` lifetime is some lifetime that is longer than `Self`.
/// Data from the value may borrow using `'ctx`.
///
/// The way to use a walker is as follows.
/// - Call [From::from()] with a value to be walked to make a walker.
/// - Call [Self::walk()] to walk the value. Data will be sent to the provided
/// visitor.
pub trait Walker<'ctx> {
type Effect: Effect<'ctx, Result<Self::Output, Self::Error>>;
type Error;
/// An arbitrary type the walker is left with after walking.
///
/// Its recommended that this is `Self` if the walker is repeatable.
type Output;
/// Walk the value.
///
/// The walker should send data to the `visitor` as it walks the value.
#[must_use]
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx, Self::Effect>,
) -> Yield<'a, 'ctx, Result<Self::Output, Self::Error>, Self::Effect>
where
Self: 'a,
'ctx: 'a;
}