preserves_schema/compiler/
cycles.rs1use preserves::value::Set;
2
3use crate::gen::schema::ModulePath;
4use crate::gen::schema::Ref;
5
6pub struct WalkState<T> {
7 pub context: T,
8 pub module_path: ModulePath,
9 seen: Set<Ref>,
10}
11
12impl<T> WalkState<T> {
13 pub fn new(context: T, module_path: ModulePath) -> Self {
14 WalkState {
15 context,
16 module_path,
17 seen: Set::new(),
18 }
19 }
20
21 pub fn cycle_check<
22 E,
23 F: Fn(&T, &Ref) -> Option<E>,
24 R,
25 Ks: FnOnce(&mut Self, Option<E>) -> R,
26 Kf: FnOnce() -> R,
27 >(
28 &mut self,
29 r: &Ref,
30 step: F,
31 ks: Ks,
32 kf: Kf,
33 ) -> R {
34 let r = r.qualify(&self.module_path);
35 if self.seen.contains(&r) {
36 kf()
37 } else {
38 self.seen.insert(r.clone());
39 let maybe_e = step(&self.context, &r);
40 let saved = std::mem::replace(&mut self.module_path, r.module);
41 let result = ks(self, maybe_e);
42 self.module_path = saved;
43 result
44 }
45 }
46}