Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
// Worst last. Maintenance ranks below every real problem: an outage elsewhere
// during planned work is still the headline.
const RANK: [&str; 5] = ["operational", "maintenance", "degraded", "partial-outage", "major-outage"];
const HEADLINE: [&str; 5] = [
"All systems operational",
"Scheduled maintenance",
"Degraded performance",
"Partial outage",
"Major outage",
];
/// The banner for a whole status page: the worst component state wins.
///
/// # Panics
/// Panics on no components, an empty or duplicate name, or an unknown state.
pub fn status_page(components: &[Component]) -> StatusSummary {
if components.is_empty() {
panic!("components must not be empty");
}
let mut seen: Vec<&str> = Vec::new();
let mut worst = 0usize;
let mut affected: Vec<String> = Vec::new();
for c in components {
if c.name.is_empty() {
panic!("component name must not be empty");
}
if seen.contains(&c.name.as_str()) {
panic!("duplicate component name: {}", c.name);
}
seen.push(&c.name);
let rank = match RANK.iter().position(|r| *r == c.state) {
Some(r) => r,
None => panic!("unknown component state: {}", c.state),
};
if rank > worst {
worst = rank;
}
if rank > 0 {
affected.push(c.name.clone());
}
}
StatusSummary {
state: RANK[worst].to_string(),
headline: HEADLINE[worst].to_string(),
affected,
}
}
/// A `Component` from its JSON form, for adapters of capabilities built on this one.
pub fn component_from_value(v: &Value) -> Component {
Component { name: v.get("name").as_str().to_string(), state: v.get("state").as_str().to_string() }
}
pub fn status_summary_to_value(s: &StatusSummary) -> Value {
Value::obj(vec![
("state", Value::str(&s.state)),
("headline", Value::str(&s.headline)),
("affected", Value::Arr(s.affected.iter().map(|a| Value::str(a)).collect())),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
let components: Vec<Component> = args[0].as_arr().iter().map(component_from_value).collect();
status_summary_to_value(&status_page(&components))
}