1use tracing::{instrument, trace};
4use uniplate::{Uniplate, tagged_zipper::TaggedZipper, zipper::Zipper};
5
6use crate::{cache::RewriteCache, events::EventHandlers, rule::Rule};
7
8#[derive(Debug, Clone)]
9pub(crate) struct EngineNodeState {
10 dirty_from: usize,
13 pass_through_until: Option<usize>,
14}
15
16impl EngineNodeState {
17 fn set_dirty_from(&mut self, level: usize) {
19 self.dirty_from = level;
20 }
21
22 fn is_dirty(&self, level: usize) -> bool {
25 level >= self.dirty_from
26 }
27}
28
29impl EngineNodeState {
30 fn new<T: Uniplate>(_: &T) -> Self {
31 Self {
32 dirty_from: 0,
33 pass_through_until: None,
34 }
35 }
36}
37
38pub(crate) struct EngineZipper<'a, T, M, R, C>
40where
41 T: Uniplate,
42 R: Rule<T, M>,
43 C: RewriteCache<T>,
44{
45 inner: TaggedZipper<T, EngineNodeState, fn(&T) -> EngineNodeState>,
46 event_handlers: &'a EventHandlers<T, M, R>,
47 down_predicate: fn(&T) -> bool,
48 pub(crate) cache: &'a mut C,
49 pub(crate) meta: M,
50}
51
52impl<'a, T, M, R, C> EngineZipper<'a, T, M, R, C>
53where
54 T: Uniplate,
55 R: Rule<T, M>,
56 C: RewriteCache<T>,
57{
58 pub fn new(
59 tree: T,
60 meta: M,
61 down_predicate: fn(&T) -> bool,
62 event_handlers: &'a EventHandlers<T, M, R>,
63 cache: &'a mut C,
64 ) -> Self {
65 EngineZipper {
66 inner: TaggedZipper::new(tree, EngineNodeState::new),
67 event_handlers,
68 down_predicate,
69 cache,
70 meta,
71 }
72 }
73
74 pub fn focus(&self) -> &T {
76 self.inner.focus()
77 }
78
79 pub fn focus_and_meta(&mut self) -> (&T, &mut M) {
82 (self.inner.focus(), &mut self.meta)
83 }
84
85 pub fn replace_focus(&mut self, replacement: T) {
87 self.inner.replace_focus(replacement);
88 }
89
90 #[instrument(skip(self))]
94 pub fn go_next_dirty(&mut self, level: usize) -> Option<()> {
95 if self.inner.tag().is_dirty(level) {
96 let pass_through = self.inner.tag().pass_through_until;
97 match pass_through {
98 Some(n) if level <= n => {
99 if level == n {
100 self.inner.tag_mut().pass_through_until = None;
101 }
102 }
104 _ => {
105 return Some(());
106 }
107 }
108 }
109
110 self.go_down()
111 .and_then(|_| {
112 loop {
114 if self.inner.tag().is_dirty(level) {
115 return Some(());
116 } else if self.go_right().is_none() {
117 self.go_up();
119 return None;
120 }
121 }
122 })
123 .or_else(|| {
124 loop {
127 if self.go_right().is_some() {
128 if self.inner.tag().is_dirty(level) {
129 return Some(());
130 }
131 } else if self.go_up().is_none() {
132 return None;
134 }
135 }
136 })
137 }
138
139 fn go_down(&mut self) -> Option<()> {
140 if !(self.down_predicate)(self.inner.focus()) {
141 return None;
142 }
143 self.cache.push_ancestor(self.inner.focus());
144 if self.inner.go_down().is_none() {
145 self.cache.pop_ancestor(); return None;
147 }
148 trace!("Go down");
149 self.event_handlers
150 .trigger_after_down(self.inner.focus(), &mut self.meta);
151 Some(())
152 }
153
154 fn go_up(&mut self) -> Option<()> {
155 if !self.inner.zipper().has_up() {
156 return None;
157 }
158 self.event_handlers
159 .trigger_before_up(self.inner.focus(), &mut self.meta);
160 self.inner.go_up().expect("checked above");
161 self.cache.pop_ancestor();
162 trace!("Go up");
163 self.event_handlers
164 .trigger_after_up(self.inner.focus(), &mut self.meta);
165 Some(())
166 }
167
168 fn go_right(&mut self) -> Option<()> {
169 if !self.inner.zipper().has_right() {
170 return None;
171 }
172 self.event_handlers
173 .trigger_before_right(self.inner.focus(), &mut self.meta);
174 self.inner.go_right().expect("checked above");
175 trace!("Go right");
176 self.event_handlers
177 .trigger_after_right(self.inner.focus(), &mut self.meta);
178 Some(())
179 }
180
181 pub fn trigger_cache_hit(&mut self) {
183 self.event_handlers
184 .trigger_on_cache_hit(self.inner.focus(), &mut self.meta);
185 }
186
187 pub fn trigger_cache_miss(&mut self) {
189 self.event_handlers
190 .trigger_on_cache_miss(self.inner.focus(), &mut self.meta);
191 }
192
193 pub fn set_dirty_from(&mut self, level: usize) {
196 trace!("Setting level = {}", level);
197 self.inner.tag_mut().set_dirty_from(level);
198 }
199
200 pub fn set_pass_through(&mut self, level: usize) {
202 self.inner.tag_mut().pass_through_until = Some(level);
203 }
204
205 pub fn mark_dirty_to_root(&mut self, level: usize) {
208 trace!("Marking Dirty to Root");
209 self.set_dirty_from(0);
210 self.cache.invalidate_node(self.inner.focus());
211 while self.inner.zipper().has_up() {
212 self.event_handlers
213 .trigger_before_up(self.inner.focus(), &mut self.meta);
214 self.inner.go_up().expect("checked above");
215 self.set_dirty_from(0);
216 self.cache.invalidate_node(self.inner.focus());
217 self.cache.pop_and_map_ancestor(self.inner.focus(), level);
218 trace!("Go up (mark dirty)");
219 self.event_handlers
220 .trigger_after_up(self.inner.focus(), &mut self.meta);
221 }
222 }
223}
224
225impl<T, M, R, C> From<EngineZipper<'_, T, M, R, C>> for (T, M)
226where
227 T: Uniplate,
228 R: Rule<T, M>,
229 C: RewriteCache<T>,
230{
231 fn from(val: EngineZipper<'_, T, M, R, C>) -> Self {
232 let meta = val.meta;
233 let tree = val.inner.rebuild_root();
234 (tree, meta)
235 }
236}
237
238pub(crate) struct NaiveZipper<'a, T, M, R, C>
240where
241 T: Uniplate,
242 R: Rule<T, M>,
243 C: RewriteCache<T>,
244{
245 inner: Zipper<T>,
246 event_handlers: &'a EventHandlers<T, M, R>,
247 down_predicate: fn(&T) -> bool,
248 pub(crate) cache: &'a mut C,
249 pub(crate) meta: M,
250}
251
252impl<'a, T, M, R, C> NaiveZipper<'a, T, M, R, C>
253where
254 T: Uniplate,
255 R: Rule<T, M>,
256 C: RewriteCache<T>,
257{
258 pub fn new(
259 tree: T,
260 meta: M,
261 down_predicate: fn(&T) -> bool,
262 event_handlers: &'a EventHandlers<T, M, R>,
263 cache: &'a mut C,
264 ) -> Self {
265 NaiveZipper {
266 inner: Zipper::new(tree),
267 event_handlers,
268 down_predicate,
269 cache,
270 meta,
271 }
272 }
273
274 pub fn focus(&self) -> &T {
276 self.inner.focus()
277 }
278
279 pub fn focus_and_meta(&mut self) -> (&T, &mut M) {
281 (self.inner.focus(), &mut self.meta)
282 }
283
284 pub fn replace_focus(&mut self, replacement: T) {
286 self.inner.replace_focus(replacement);
287 }
288
289 pub fn trigger_cache_hit(&mut self) {
291 self.event_handlers
292 .trigger_on_cache_hit(self.inner.focus(), &mut self.meta);
293 }
294
295 pub fn trigger_cache_miss(&mut self) {
297 self.event_handlers
298 .trigger_on_cache_miss(self.inner.focus(), &mut self.meta);
299 }
300
301 pub fn into_parts(self) -> (T, M) {
303 (self.inner.rebuild_root(), self.meta)
304 }
305
306 pub fn get_next(&mut self) -> Option<()> {
307 if (self.down_predicate)(self.inner.focus()) {
310 self.cache.push_ancestor(self.inner.focus());
311 if self.inner.go_down().is_some() {
312 return Some(());
313 }
314 self.cache.pop_ancestor();
315 }
316 if self.inner.go_right().is_some() {
317 return Some(());
318 }
319 while self.inner.go_up().is_some() {
320 self.cache.pop_ancestor();
321 if self.inner.go_right().is_some() {
322 return Some(());
323 }
324 }
325 None
326 }
327
328 pub fn map_ancestors_to_root(&mut self, level: usize) {
330 while self.inner.has_up() {
331 self.event_handlers
332 .trigger_before_up(self.inner.focus(), &mut self.meta);
333 self.inner.go_up().expect("checked above");
334 self.cache.invalidate_node(self.inner.focus());
335 self.cache.pop_and_map_ancestor(self.inner.focus(), level);
336 trace!("Go up (map ancestor)");
337 self.event_handlers
338 .trigger_after_up(self.inner.focus(), &mut self.meta);
339 }
340 }
341}