directed_visit/
direct.rs

1use crate::{DirectorVisitor, Visit, Visitor};
2
3/// A wrapper for a [Direct] implementation.
4#[derive(Debug)]
5pub struct Director<'dv, D: ?Sized, V: ?Sized>(DirectorVisitor<'dv, D, V>);
6
7impl<'dv, D: ?Sized, V: ?Sized> Director<'dv, D, V> {
8    pub(crate) fn new(data: DirectorVisitor<'dv, D, V>) -> Self {
9        Self(data)
10    }
11
12    /// Direct from this node to a sub-node with the [Visit] implementation.
13    pub fn direct<NN: ?Sized>(this: &mut Self, node: &NN)
14    where
15        D: Direct<V, NN>,
16        V: Visit<NN>,
17    {
18        <V as Visit<NN>>::visit(Visitor::new(this.0.reborrow(), node), node)
19    }
20}
21
22impl<D: ?Sized, V: ?Sized> std::ops::Deref for Director<'_, D, V> {
23    type Target = D;
24
25    fn deref(&self) -> &Self::Target {
26        self.0.direct
27    }
28}
29
30impl<D: ?Sized, V: ?Sized> std::ops::DerefMut for Director<'_, D, V> {
31    fn deref_mut(&mut self) -> &mut Self::Target {
32        self.0.direct
33    }
34}
35
36/// Determines how to traverse the nodes within the input. This must be implemented for
37/// all node types in the input.
38pub trait Direct<V: ?Sized, N: ?Sized> {
39    /// Determines all the sub-nodes of the given node. For each sub-node, call
40    /// `Director::direct(&mut director, &node.my_subnode)`.
41    fn direct(director: Director<'_, Self, V>, node: &N);
42}