Functional Weave
Code in TypeScript

monitor.series-window@1.0.0

impl/rust.rs

1,814 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

/// The samples with from <= at < to. Half-open, so consecutive windows
/// (the last hour, the hour before) never count a sample twice.
///
/// # Panics
/// Panics when from is after to, or the samples are not strictly ascending.
pub fn series_window(samples: &[MetricSample], from: i64, to: i64) -> Vec<MetricSample> {
    if from > to {
        panic!("from must not be after to: {} > {}", from, to);
    }
    let mut out = Vec::new();
    for (i, s) in samples.iter().enumerate() {
        // Checked over the whole series, not just the window: a misordered
        // store gives wrong answers everywhere, so it should fail everywhere.
        if i > 0 && s.at <= samples[i - 1].at {
            panic!("samples must be in strictly ascending time order: {} follows {}", s.at, samples[i - 1].at);
        }
        if s.at >= from && s.at < to {
            out.push(MetricSample { at: s.at, value: s.value });
        }
    }
    out
}

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

pub fn samples_from_value(v: &Value) -> Vec<MetricSample> {
    v.as_arr().iter().map(sample_from_value).collect()
}

pub fn sample_to_value(s: &MetricSample) -> Value {
    Value::obj(vec![("at", Value::Int(s.at)), ("value", Value::Int(s.value))])
}

fn whole(v: &Value) -> i64 {
    match v {
        Value::Int(i) => *i,
        _ => panic!("from and to must be whole seconds"),
    }
}

pub fn fune_vector(args: &[Value]) -> Value {
    let samples = samples_from_value(&args[0]);
    let out = series_window(&samples, whole(&args[1]), whole(&args[2]));
    Value::Arr(out.iter().map(sample_to_value).collect())
}