Skip to main content

netspeed_cli/
phase_registry.rs

1//! Registry for phase functions allowing open/closed extension.
2use crate::orchestrator::Orchestrator;
3use crate::phases::{PhaseContext, PhaseFn, PhaseOutcome};
4use std::collections::HashMap;
5// Arc not needed – phases are stored in a Vec
6
7/// Holds the ordered list of phases.
8#[derive(Default)]
9pub struct PhaseRegistry {
10    phases: Vec<PhaseFn>,
11    // optional map for named lookup if needed later
12    #[allow(dead_code)]
13    map: HashMap<String, usize>,
14}
15
16impl PhaseRegistry {
17    /// Create a new empty registry.
18    pub fn new() -> Self {
19        Self::default()
20    }
21
22    /// Register a phase function (pushes to end of execution order).
23    pub fn register(&mut self, name: impl Into<String>, phase: PhaseFn) {
24        let idx = self.phases.len();
25        self.map.insert(name.into(), idx);
26        self.phases.push(phase);
27    }
28
29    /// Iterate over registered phases.
30    pub fn iter(&self) -> impl Iterator<Item = &PhaseFn> {
31        self.phases.iter()
32    }
33}
34
35/// Execute all registered phases using the provided orchestrator.
36pub async fn run_all_registered(
37    orch: &Orchestrator,
38    registry: &PhaseRegistry,
39) -> Result<(), crate::error::Error> {
40    let mut ctx = PhaseContext::new(orch.services_arc());
41    for phase in registry.iter() {
42        match phase(orch, &mut ctx).await {
43            PhaseOutcome::PhaseCompleted => {}
44            PhaseOutcome::PhaseEarlyExit => break,
45            PhaseOutcome::PhaseError(e) => return Err(e),
46        }
47    }
48    Ok(())
49}