directed_visit/
visit.rs

1use crate::{Direct, Director, DirectorVisitor};
2
3/// A wrapper for a [Visit] implementation.
4#[derive(Debug)]
5pub struct Visitor<'dv, 'n, D: ?Sized, V: ?Sized, N: ?Sized>(DirectorVisitor<'dv, D, V>, &'n N);
6
7impl<'dv, 'n, D: ?Sized, V: ?Sized, N: ?Sized> Visitor<'dv, 'n, D, V, N> {
8    pub(crate) fn new(data: crate::DirectorVisitor<'dv, D, V>, node: &'n N) -> Self {
9        Self(data, node)
10    }
11
12    /// Complete visiting this node and return control to the [Direct] implementation.
13    pub fn visit(this: Self)
14    where
15        D: Direct<V, N>,
16    {
17        <D as Direct<V, N>>::direct(Director::new(this.0), this.1)
18    }
19}
20
21impl<D: ?Sized, V: ?Sized, N: ?Sized> std::ops::Deref for Visitor<'_, '_, D, V, N> {
22    type Target = V;
23
24    fn deref(&self) -> &Self::Target {
25        self.0.visit
26    }
27}
28
29impl<D: ?Sized, V: ?Sized, N: ?Sized> std::ops::DerefMut for Visitor<'_, '_, D, V, N> {
30    fn deref_mut(&mut self) -> &mut Self::Target {
31        self.0.visit
32    }
33}
34
35/// The action to be performed when visiting a node of type `N`. This trait must be
36/// implemented for all node types in the input, even if the visitor has no special handling
37/// for that type.
38pub trait Visit<N: ?Sized> {
39    /// Performs the visiting action. The default implementation simply calls
40    /// `Visitor::visit(visitor)`, which returns control to the [Direct] implementation
41    /// to continue to further sub-nodes. If you wish to skip sub-nodes, simply omit this
42    /// call from your implementation.
43    fn visit<'n, D>(visitor: Visitor<'_, 'n, D, Self, N>, _node: &'n N)
44    where
45        D: Direct<Self, N> + ?Sized,
46    {
47        Visitor::visit(visitor);
48    }
49}