is_tree/
visitor_macro.rs

1#[macro_export]
2macro_rules! chain {
3    () => {
4        std::iter::empty()
5    };
6
7    ($x:expr) => {
8        $x
9    };
10
11    ($x:expr, $($xs:expr),+) => {
12        $x.chain(chain!($($xs),+))
13    };
14}
15
16///! A macro for generating visitor types.
17/// Example:
18/// ```rust,ignore
19/// use ::is_tree::*;
20/// visitor! {
21///    pub enum Visitors, VisitorMut {
22///       Root(Root visits [Type1]),
23///       Branches(
24///         Branch1 visits [Type1, Type2, Type3],
25///         Branch2 visits [Type2, Type4],
26///         Branch3
27///       )
28///    }
29/// }
30/// ```
31#[macro_export]
32macro_rules! visitor {
33    (
34        $($access:tt)? enum $name:ident, $name_mut:ident {
35            Root($root:ident $(visits [$($root_host:ident),*])?),
36            Branches(
37                $($branch:ident $(visits [$($branch_host:ident),*])?),*
38            )
39        }
40    ) => {
41        use $crate::*;
42
43        #[derive(Debug, Clone, $crate::prelude::EnumAsInner)]
44        $($access)? enum $name<'a> {
45            $root($crate::Visitor<(), &'a $root>),
46            $($branch($crate::Visitor<Box<$name<'a>>, &'a $branch>)),*
47        }
48
49        #[derive(Debug, $crate::prelude::EnumAsInner)]
50        $($access)? enum $name_mut<'a> {
51            $root($crate::Visitor<(), &'a mut $root>),
52            $($branch($crate::Visitor<Box<$name<'a>>, &'a mut $branch>)),*
53        }
54
55        unsafe impl<'a> UnsafeFrom<Box<$name<'a>>> for $name_mut<'a> {
56            unsafe fn unsafe_from(visitor: Box<$name>) -> Self {
57                let visitor = *visitor;
58                unsafe { std::mem::transmute(visitor) }
59            }
60        }
61
62        impl<'a> From<&&'a mut $name_mut<'a>> for $name<'a> { // TODO: Is this unsafe? Can we get & from &mut? Should we use UnsafeFrom here?
63            fn from(visitor: &&'a mut $name_mut<'a>) -> Self {
64                unsafe {
65                    (*(std::mem::transmute::<_, &&$name<'a>>(visitor))).clone()
66                }
67            }
68        }        
69
70        impl<'a> From<$crate::Visitor<(), &'a $root>> for $name<'a> {
71            fn from(visitor: $crate::Visitor<(), &'a $root>) -> Self {
72                Self::$root(visitor)
73            }
74        }
75
76        impl<'a> From<$crate::Visitor<(), &'a mut $root>> for $name_mut<'a> {
77            fn from(visitor: $crate::Visitor<(), &'a mut $root>) -> Self {
78                Self::$root(visitor)
79            }
80        }
81
82        impl<'a> From<&'a $root> for $name<'a> {
83            fn from(branch: &'a $root) -> Self {
84                Self::$root($crate::Visitor::new((), branch))
85            }
86        }
87
88        impl<'a> From<&'a mut $root> for $name_mut<'a> {
89            fn from(branch: &'a mut $root) -> Self {
90                Self::$root($crate::Visitor::new((), branch))
91            }
92        }
93
94        impl<'a> From<Box<$name<'a>>> for $name<'a> {
95            fn from(visitor: Box<$name<'a>>) -> Self {
96                *visitor
97            }
98        }
99
100        impl<'a> From<Box<$name_mut<'a>>> for $name_mut<'a> {
101            fn from(visitor: Box<$name_mut<'a>>) -> Self {
102                *visitor
103            }
104        }
105
106        $(
107            impl<'a> From<$crate::Visitor<Box<$name<'a>>, &'a $branch>> for $name<'a> {
108                fn from(visitor: $crate::Visitor<Box<$name<'a>>, &'a $branch>) -> Self {
109                    Self::$branch(visitor)
110                }
111            }
112
113            impl<'a> From<$crate::Visitor<Box<$name<'a>>, &'a mut $branch>> for $name<'a> {
114                fn from(visitor: $crate::Visitor<Box<$name<'a>>, &'a mut $branch>) -> Self {
115                    unsafe { Self::$branch(std::mem::transmute(visitor)) }
116                }
117            }
118
119            impl<'a> From<$crate::Visitor<Box<$name<'a>>, &'a mut $branch>> for $name_mut<'a> {
120                fn from(visitor: $crate::Visitor<Box<$name<'a>>, &'a mut $branch>) -> Self {
121                    Self::$branch(visitor)
122                }
123            }
124        )*
125
126        impl<'a> KnowsVisitor for $name<'a> {
127            type Visitor = $name<'a>;
128            type VisitorMut = $name_mut<'a>;
129        }
130
131        impl<'a> KnowsVisitor for $name_mut<'a> {
132            type Visitor = $name<'a>;
133            type VisitorMut = $name_mut<'a>;
134        }
135
136        unsafe impl<'a> UnsafeClone for $name<'a> {
137            unsafe fn unsafe_clone(&self) -> Self {
138                self.clone()
139            }
140        }
141
142        unsafe impl<'a> UnsafeClone for $name_mut<'a> {
143            unsafe fn unsafe_clone(&self) -> Self {
144                let visitor: &$name = std::mem::transmute(self);
145                let visitor = visitor.clone();
146                std::mem::transmute(visitor)
147            }
148        }
149
150        unsafe impl<'a> UnsafeBorrow<'a> for $name<'a> {
151            type Borrow = &'a $name<'a>;
152            unsafe fn borrow(&'a self) -> Self::Borrow {
153                self
154            }
155        }
156
157        unsafe impl<'a> UnsafeBorrow<'a> for $name_mut<'a> {
158            type Borrow = &'a mut $name_mut<'a>;
159            unsafe fn borrow(&'a self) -> Self::Borrow {
160                #[allow(mutable_transmutes)]
161                unsafe { std::mem::transmute(self) }
162            }
163        }
164
165        impl<'a> HasPathSegment for $name<'a> {
166            fn path_segment(&self) -> String {
167                match self {
168                    $name::$root(visitor) => visitor.path_segment(),
169                    $($name::$branch(visitor) => visitor.path_segment()),*
170                }
171            }
172        }
173
174        impl<'a> HasPathSegment for $name_mut<'a> {
175            fn path_segment(&self) -> String {
176                match self {
177                    $name_mut::$root(visitor) => visitor.path_segment(),
178                    $($name_mut::$branch(visitor) => visitor.path_segment()),*
179                }
180            }
181        }
182
183        impl<'a> HasPath for $name<'a> {
184            fn path(&self) -> Path {
185                match self {
186                    $name::$root(visitor) => visitor.path(),
187                    $($name::$branch(visitor) => visitor.path()),*
188                }
189            }
190        }        
191
192        impl<'a> HasPath for $name_mut<'a> {
193            fn path(&self) -> Path {
194                match self {
195                    $name_mut::$root(visitor) => visitor.path(),
196                    $($name_mut::$branch(visitor) => visitor.path()),*
197                }
198            }
199        }        
200
201        impl<'a> HasParent for $name<'a> {
202            fn parent(&self) -> Option<Self> {
203                match self {
204                    $name::$root(_) => None,
205                    $($name::$branch(visitor) => Some((*visitor.parent).clone())),*
206                }
207            }
208        }
209
210        impl<'a> HasParent for $name_mut<'a> {
211            fn parent(&self) -> Option<Self::Visitor> {
212                match self {
213                    $name_mut::$root(_) => None,
214                    $($name_mut::$branch(visitor) => Some((*visitor.parent).clone())),*
215                }
216            }
217        }
218
219        unsafe impl<'a> HasParentMut for $name_mut<'a> {
220            unsafe fn parent_mut(&mut self) -> Option<Self> {
221                match self {
222                    $name_mut::Library(_) => None,
223                    $($name_mut::$branch(visitor) => {
224                        let visitor: $name = *visitor.parent.clone();
225                        let visitor = std::mem::transmute(visitor);
226                        Some(visitor)
227                    }),*
228                }
229            }
230        }
231
232        impl<'a> std::ops::Deref for $name_mut<'a> {
233            type Target = $name<'a>;
234            fn deref(&self) -> &Self::Target {
235                self
236            }
237        }
238
239        impl<'a> std::ops::DerefMut for $name_mut<'a> {
240            fn deref_mut(&mut self) -> &mut Self::Target {
241                self
242            }
243        }
244
245        impl<'a> HasRoot for $name<'a> {
246            fn root(&self) -> Self {
247                match self {
248                    $name::$root(_) => self.clone(),
249                    $($name::$branch(visitor) => visitor.parent.root()),*
250                }
251            }
252        }
253
254        unsafe impl<'a> HasRootMut for $name<'a> {
255            unsafe fn root_mut(&mut self) -> Self::VisitorMut {
256                match self {
257                    $name::Library(_) => std::mem::transmute(self.unsafe_clone()),
258                    $($name::$branch(visitor) => {
259                        let visitor: $name = visitor.parent.root();
260                        let visitor = std::mem::transmute(visitor);
261                        visitor
262                    }),*
263                }
264            }
265        }
266
267        impl<'a> HasRoot for $name_mut<'a> {
268            fn root(&self) -> Self::Visitor {
269                match self {
270                    $name_mut::$root(_) => unsafe { std::mem::transmute(self.unsafe_clone()) },
271                    $($name_mut::$branch(visitor) => visitor.parent.root()),*
272                }
273            }
274        }
275
276        unsafe impl<'a> HasRootMut for $name_mut<'a> {
277            unsafe fn root_mut(&mut self) -> Self {
278                match self {
279                    $name_mut::Library(_) => self.unsafe_clone(),
280                    $($name_mut::$branch(visitor) => {
281                        let visitor: $name = visitor.parent.root();
282                        let visitor = std::mem::transmute(visitor);
283                        visitor
284                    }),*
285                }
286            }
287        }
288
289        impl<'a> $crate::HasBranches<$name<'a>> for &'a $name<'a> {
290            fn branches_impl(self) -> impl Iterator<Item = $name<'a>> {
291                match self {
292                    $name::$root(visitor) => Box::new(
293                        chain!(
294                            $(
295                                $(
296                                    visitor.value.branches_impl2::<&$root_host>().map(|branch| $crate::Visitor::new(self.clone().into(), branch).into())
297                                ),*
298                            )?
299                        )
300                    ) as Box<dyn Iterator<Item = _>>,
301                    $($name::$branch(visitor) => {
302                        Box::new(
303                            chain!(
304                                $(
305                                    $(
306                                        visitor.value.branches_impl2::<&$branch_host>().map(|branch| $crate::Visitor::new(self.clone().into(), branch).into())
307                                    ),*
308                                )?
309                            )
310                        ) as Box<dyn Iterator<Item = _>>
311                    }),*
312                }
313            }
314        }
315
316        // impl<'a> $crate::HasBranches<$name<'a>> for &'a mut $name_mut<'a> {
317        //     fn branches_impl(self) -> impl Iterator<Item = $name<'a>> {
318        //         let self_: &'a $name<'a> = unsafe { std::mem::transmute(self) };
319        //         self_.branches_impl()
320        //     }
321        // }
322
323        impl<'a> $crate::HasBranches<$name_mut<'a>> for &'a mut $name_mut<'a> {
324            fn branches_impl(self) -> impl Iterator<Item = $name_mut<'a>> {
325                let parent = Box::new($name::from(&self));
326                match self {
327                    $name_mut::$root(visitor) => Box::new(
328                        chain!(
329                            $(
330                                $(
331                                    {
332                                        let parent_clone = parent.clone();
333                                        let visitor = unsafe { longer_mut(visitor) };
334                                        visitor.value.branches_impl2::<&mut $root_host>().map(move |branch| $crate::Visitor::new(parent_clone.clone(), branch).into())
335                                    }
336                                ),*
337                            )?
338                        )
339                    ) as Box<dyn Iterator<Item = _>>,
340                    $($name_mut::$branch(visitor) => {
341                        Box::new(
342                            chain!(
343                                $(
344                                    $(
345                                        {
346                                            let parent_clone = parent.clone();
347                                            let visitor = unsafe { longer_mut(visitor) };
348                                            visitor.value.branches_impl2::<&mut $branch_host>().map(move |branch| $crate::Visitor::new(parent_clone.clone(), branch).into())
349                                        }
350                                    ),*
351                                )?
352                            )
353                        ) as Box<dyn Iterator<Item = _>>
354                    }),*
355                }
356            }
357        }        
358    };
359}