preserves/implementations/rust/preserves-schema/src/compiler/cycles.rs

47 lines
1.0 KiB
Rust

use preserves::value::Set;
use crate::gen::schema::ModulePath;
use crate::gen::schema::Ref;
pub struct WalkState<T> {
pub context: T,
pub module_path: ModulePath,
seen: Set<Ref>,
}
impl<T> WalkState<T> {
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<E>,
R,
Ks: FnOnce(&mut Self, Option<E>) -> 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
}
}
}