directed_visit/
visit.rs

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