use preserves::value::Set; use crate::gen::schema::ModulePath; use crate::gen::schema::Ref; pub struct WalkState { pub context: T, pub module_path: ModulePath, seen: Set, } impl WalkState { pub fn new(context: T, module_path: ModulePath) -> Self { WalkState { context, module_path, seen: Set::new(), } } pub fn cycle_check< E, F: Fn(&T, &Ref) -> Option, R, Ks: FnOnce(&mut Self, Option) -> R, Kf: FnOnce() -> R, >( &mut self, r: &Ref, step: F, ks: Ks, kf: Kf, ) -> R { let r = r.qualify(&self.module_path); if self.seen.contains(&r) { kf() } else { self.seen.insert(r.clone()); let maybe_e = step(&self.context, &r); let saved = std::mem::replace(&mut self.module_path, r.module); let result = ks(self, maybe_e); self.module_path = saved; result } } }