use std::collections::BTreeSet; use std::path::Path; use crate::Result; #[derive(Debug, Default, Clone, Copy, Eq, Hash, PartialEq, Ord, PartialOrd)] pub enum Stage { #[default] All, Parse, AddImplicitEdges, AddInitEdges, AddJumpEdges, } impl Stage { pub const ALL: &'static [Stage] = &[ Stage::All, Stage::Parse, Stage::AddImplicitEdges, Stage::AddInitEdges, Stage::AddJumpEdges, ]; pub fn name(self) -> &'static str { match self { Stage::All => "all", Stage::Parse => "parse", Stage::AddImplicitEdges => "add-implicit-edges", Stage::AddInitEdges => "add-init-edges", Stage::AddJumpEdges => "add-jump-edges", } } pub fn prerequisites(self) -> &'static [Stage] { match self { Stage::All => &[ Stage::AddImplicitEdges, Stage::AddInitEdges, Stage::AddJumpEdges, ], Stage::Parse => &[], Stage::AddImplicitEdges => &[Stage::Parse], Stage::AddInitEdges => &[Stage::Parse], Stage::AddJumpEdges => &[Stage::Parse], } } pub fn with_prerequisites(self) -> Vec { self.with_prerequisites_impl(BTreeSet::new()) } fn with_prerequisites_impl(self, seen: BTreeSet) -> Vec { if seen.contains(&self) { return Vec::new(); } let mut seen = seen; seen.insert(self); let mut stages = Vec::new(); for prerequisite in self.prerequisites() { let prerequisite_stages = prerequisite.with_prerequisites_impl(seen.clone()); seen.extend(prerequisite_stages.iter().copied()); stages.extend(prerequisite_stages); } if self != Stage::All { stages.push(self); } stages } } pub fn run_stage(stage: Stage, output_dir: &Path) -> Result<()> { match stage { Stage::All => Ok(()), Stage::Parse => run_parse(output_dir), Stage::AddImplicitEdges => run_add_implicit_edges(output_dir), Stage::AddInitEdges => run_add_init_edges(output_dir), Stage::AddJumpEdges => run_add_jump_edges(output_dir), } } fn run_parse(_output_dir: &Path) -> Result<()> { Ok(()) } fn run_add_implicit_edges(_output_dir: &Path) -> Result<()> { Ok(()) } fn run_add_init_edges(_output_dir: &Path) -> Result<()> { Ok(()) } fn run_add_jump_edges(_output_dir: &Path) -> Result<()> { Ok(()) }