is_tree/
visitor.rs

1//! Visitor pattern for tree traversal.
2
3use crate::{longer_ref, HasBranches, HasParent, HasPath, HasPathSegment, HasRoot, KnowsVisitor, Path, UnsafeClone, UnsafeFrom, HasParentMut, HasRootMut};
4
5/// A visitor for tree traversal.
6#[derive(Clone, Debug, Default)]
7pub struct Visitor<Parent, Value> {
8    /// The parent of the visitor.
9    pub parent: Parent,
10    /// The value of the visitor.
11    pub value: Value
12}
13
14impl<Parent, Value> Visitor<Parent, Value> {
15    /// Creates a new visitor.
16    pub fn new(parent: Parent, value: Value) -> Self {
17        Self { parent, value }
18    }
19}
20
21impl<Parent, Value> HasPathSegment for Visitor<Parent, Value>
22where Value: HasPathSegment
23{
24    fn path_segment(&self) -> String {
25        self.value.path_segment()
26    }
27}
28
29impl<Parent, Value> HasPath for Visitor<Parent, Value>
30where Value: HasPathSegment,
31      Parent: HasPath
32{
33    fn path(&self) -> Path
34    {
35        let mut path = self.parent.path();
36        path.segments.push(self.value.path_segment());
37        path
38    }
39}
40
41// Parent as Visitor is a convention because it's always a Box<T> where T is an enumeration visitor defined with `visitor!`.
42impl<Parent, Value> KnowsVisitor for Visitor<Parent, Value>
43where Parent: KnowsVisitor
44{
45    type Visitor = Parent::Visitor;
46    type VisitorMut = Parent::VisitorMut;
47}
48
49unsafe impl<Parent, Value> UnsafeClone for Visitor<Parent, &mut Value>
50where Parent: Clone
51{
52    unsafe fn unsafe_clone(&self) -> Self {
53        let parent = self.parent.clone();
54        let value = std::mem::transmute_copy(&self.value);
55        Self { parent, value }
56    }
57}
58
59unsafe impl<'a, Parent, Value> UnsafeClone for Visitor<Parent, &'a Value>
60where Parent: Clone
61{
62    unsafe fn unsafe_clone(&self) -> Self {
63        Self { parent: self.parent.clone(), value: self.value }
64    }
65}
66
67impl<Parent, Value> HasParent for Visitor<Parent, Value>
68where
69    Self: KnowsVisitor,
70    Parent: Clone + Into<Self::Visitor>
71{
72    fn parent(&self) -> Option<Self::Visitor> {
73        Some(self.parent.clone().into())
74    }
75}
76
77unsafe impl<Parent, Value> HasParentMut for Visitor<Parent, Value>
78where
79    Self: KnowsVisitor,
80    Self::VisitorMut: UnsafeFrom<Parent>,
81    Parent: Clone
82{
83    unsafe fn parent_mut(&mut self) -> Option<Self::VisitorMut> {
84        Some(Self::VisitorMut::unsafe_from(self.parent.clone()))
85    }
86}
87
88impl<Parent, Value> HasRoot for Visitor<Parent, Value>
89where
90    Self: KnowsVisitor,
91    Parent: HasRoot,
92    Parent::Visitor: Into<Self::Visitor>
93{
94    fn root(&self) -> Self::Visitor {
95        self.parent.root().into()
96    }
97}
98
99unsafe impl<Parent, Value> HasRootMut for Visitor<Parent, Value>
100where
101    Self: KnowsVisitor,
102    Parent: HasRootMut,
103    Parent::VisitorMut: Into<Self::VisitorMut>
104{
105    unsafe fn root_mut(&mut self) -> Self::VisitorMut {
106        self.parent.root_mut().into()
107    }
108}
109
110impl<'a, Parent, Value, T> HasBranches<T> for &'a Visitor<Parent, Value>
111where
112    Visitor<Parent, Value>: UnsafeClone,
113    T: From<Visitor<Parent, Value>> + 'a,
114    &'a T: HasBranches<T>
115{
116    fn branches_impl(self) -> impl Iterator<Item = T> {
117        unsafe {
118            let self_ = longer_ref(self); // TODO: Why is this necessary?
119            let visitor = T::from(self_.unsafe_clone());
120            longer_ref(&visitor).branches_impl()
121        }
122    }
123}