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#[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> { 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_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}