use sim_kernel::Symbol;
use crate::{ConfigLayer, ProbeMode};
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct ConfigProbeCaps {
pub env: bool,
pub os: bool,
pub hardware_inventory: bool,
pub network_inventory: bool,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ConfigProbeRequest {
pub lib: Symbol,
pub mode: ProbeMode,
pub caps: ConfigProbeCaps,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConfigProbeStatus {
Applied,
Skipped {
reason: String,
},
Denied {
capability: String,
},
Failed {
message: String,
},
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ConfigProbeReport {
pub probe: Symbol,
pub lib: Symbol,
pub mode: ProbeMode,
pub status: ConfigProbeStatus,
pub emitted_keys: Vec<String>,
}
pub trait ConfigProbe {
fn symbol(&self) -> Symbol;
fn probe(&self, request: &ConfigProbeRequest) -> (Option<ConfigLayer>, ConfigProbeReport);
}
#[cfg(test)]
mod tests {
use sim_kernel::Expr;
use super::*;
use crate::{ConfigDir, ConfigSource};
struct FakeProbe {
symbol: Symbol,
}
impl FakeProbe {
fn new() -> Self {
Self {
symbol: Symbol::qualified("config", "fake"),
}
}
}
impl ConfigProbe for FakeProbe {
fn symbol(&self) -> Symbol {
self.symbol.clone()
}
fn probe(&self, request: &ConfigProbeRequest) -> (Option<ConfigLayer>, ConfigProbeReport) {
let emitted_keys = vec!["backend".to_owned()];
let layer = ConfigLayer::new(
ConfigSource::Probe {
probe: self.symbol(),
mode: request.mode,
},
ConfigDir::one(
request.lib.clone(),
Expr::Map(vec![(
Expr::Symbol(Symbol::new("backend")),
Expr::String("modeled".to_owned()),
)]),
)
.unwrap(),
);
let report = ConfigProbeReport {
probe: self.symbol(),
lib: request.lib.clone(),
mode: request.mode,
status: ConfigProbeStatus::Applied,
emitted_keys,
};
(Some(layer), report)
}
}
#[test]
fn probe_mode_defaults_to_modeled() {
assert_eq!(ProbeMode::default(), ProbeMode::Modeled);
}
#[test]
fn probe_returns_optional_layer_and_typed_report() {
let probe = FakeProbe::new();
let request = ConfigProbeRequest {
lib: Symbol::qualified("stream", "host"),
mode: ProbeMode::default(),
caps: ConfigProbeCaps::default(),
};
let (layer, report) = probe.probe(&request);
assert_eq!(report.probe, Symbol::qualified("config", "fake"));
assert_eq!(report.lib, Symbol::qualified("stream", "host"));
assert_eq!(report.mode, ProbeMode::Modeled);
assert_eq!(report.status, ConfigProbeStatus::Applied);
assert_eq!(report.emitted_keys, ["backend"]);
assert!(matches!(
layer.unwrap().source,
ConfigSource::Probe {
probe,
mode: ProbeMode::Modeled
} if probe == Symbol::qualified("config", "fake")
));
}
}