preserves_schema/compiler/
cycles.rs

1use 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}