Functional Weave
Code in TypeScript

monitor.check-status@1.0.0

impl/rust.rs

1,775 bytes · the Rust implementation · view raw

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

/// One status for a target probed from several places. Down needs a quorum,
/// so one location with a broken route cannot page anyone; a down vote below
/// the quorum still counts as degraded, because something is wrong somewhere.
///
/// # Panics
/// Panics on an empty list, a quorum outside 1..=len, or an unknown status.
pub fn aggregate_status(statuses: &[String], down_quorum: i64) -> String {
    if statuses.is_empty() {
        panic!("statuses must not be empty");
    }
    if down_quorum < 1 || down_quorum > statuses.len() as i64 {
        panic!("downQuorum must be 1 to {}, received {}", statuses.len(), down_quorum);
    }
    let mut down = 0i64;
    let mut degraded = 0i64;
    for s in statuses {
        match s.as_str() {
            "down" => down += 1,
            "degraded" => degraded += 1,
            "up" => {}
            other => panic!("unknown check status: {}", other),
        }
    }
    if down >= down_quorum {
        return "down".to_string();
    }
    if down > 0 || degraded > 0 { "degraded".to_string() } else { "up".to_string() }
}

/// A `Check` from its JSON form, for adapters of capabilities built on this one.
pub fn check_from_value(v: &Value) -> Check {
    Check { at: v.get("at").as_i64(), status: v.get("status").as_str().to_string() }
}

pub fn checks_from_value(v: &Value) -> Vec<Check> {
    v.as_arr().iter().map(check_from_value).collect()
}

pub fn check_to_value(c: &Check) -> Value {
    Value::obj(vec![("at", Value::Int(c.at)), ("status", Value::str(&c.status))])
}

pub fn fune_vector(args: &[Value]) -> Value {
    let statuses: Vec<String> = args[0].as_arr().iter().map(|s| s.as_str().to_string()).collect();
    Value::str(&aggregate_status(&statuses, args[1].as_i64()))
}