uniplate/traits/
context.rs1use std::sync::Arc;
4
5use crate::zipper::{Zipper, ZipperBi};
6
7use super::{Biplate, Uniplate};
8
9pub(super) struct ContextIter<T: Uniplate> {
11 zipper: Zipper<T>,
12 done: bool,
13}
14
15impl<T: Uniplate> ContextIter<T> {
16 pub(super) fn new(root: T) -> ContextIter<T> {
17 ContextIter {
18 zipper: Zipper::new(root),
19 done: false,
20 }
21 }
22}
23
24impl<T: Uniplate> Iterator for ContextIter<T> {
25 type Item = (T, Arc<dyn Fn(T) -> T>);
26
27 fn next(&mut self) -> Option<Self::Item> {
28 if self.done {
29 return None;
30 };
31 let node = self.zipper.focus().clone();
32 let zipper1 = self.zipper.clone();
33 let hole_fn = Arc::new(move |x| {
34 let mut zipper2 = zipper1.clone();
37 zipper2.replace_focus(x);
38 zipper2.rebuild_root()
39 });
40
41 if self.zipper.go_down().is_none() {
44 while self.zipper.go_right().is_none() {
45 if self.zipper.go_up().is_none() {
46 self.done = true;
48 break;
49 };
50 }
51 }
52
53 Some((node, hole_fn))
54 }
55}
56
57pub(super) struct ContextIterBi<T: Uniplate, U: Biplate<T>> {
59 zipper: Option<ZipperBi<T, U>>,
60 done: bool,
61}
62
63impl<T: Uniplate, U: Biplate<T>> ContextIterBi<T, U> {
64 pub(super) fn new(root: U) -> ContextIterBi<T, U> {
65 ContextIterBi {
66 zipper: ZipperBi::new(root),
67 done: false,
68 }
69 }
70}
71
72impl<T: Uniplate, U: Biplate<T>> Iterator for ContextIterBi<T, U> {
73 type Item = (T, Arc<dyn Fn(T) -> U>);
74
75 fn next(&mut self) -> Option<Self::Item> {
76 if self.done {
77 return None;
78 };
79
80 let Some(zipper) = &mut self.zipper else {
81 return None;
82 };
83
84 let node = zipper.focus().clone();
85
86 let zipper1 = zipper.clone();
87 let hole_fn = Arc::new(move |x| {
88 let mut zipper1 = zipper1.clone();
91 zipper1.replace_focus(x);
92 zipper1.rebuild_root()
93 });
94
95 if zipper.go_down().is_none() {
98 while zipper.go_right().is_none() {
99 if zipper.go_up().is_none() {
100 self.done = true;
102 break;
103 };
104 }
105 }
106
107 Some((node, hole_fn))
108 }
109}