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
/// How fast an SLO's error budget is burning, in thousandths: the window's
/// error rate divided by the error rate the SLO allows. 1000 spends exactly
/// the budget over the SLO period; 14400 (14.4x) spends 2% of a 30-day
/// budget in one hour. Exact i128 arithmetic.
///
/// # Panics
/// Panics on a target outside 1..=9999, negative counts, or more bad events than events.
pub fn burn_rate(target_basis_points: i64, total_events: i64, bad_events: i64) -> i64 {
if !(1..=9999).contains(&target_basis_points) {
panic!(
"targetBasisPoints must be a whole number from 1 to 9999 (10000 leaves no error budget), received {}",
target_basis_points
);
}
if total_events < 0 {
panic!("totalEvents must be a whole number of at least 0, received {}", total_events);
}
if bad_events < 0 {
panic!("badEvents must be a whole number of at least 0, received {}", bad_events);
}
if bad_events > total_events {
panic!("badEvents must not exceed totalEvents: {} > {}", bad_events, total_events);
}
// An empty window has no error rate; 0 keeps an alert quiet rather than failing it.
if total_events == 0 {
return 0;
}
let n = bad_events as i128 * 10000 * 1000;
let d = total_events as i128 * (10000 - target_basis_points) as i128;
((2 * n + d) / (2 * d)) as i64
}
// JSON cannot tell 2 from 2.0, and Python refuses a float, so any non-Int is refused here too.
fn whole(v: &Value, what: &str) -> i64 {
let rule = if what == "targetBasisPoints" { "from 1 to 9999 (10000 leaves no error budget)," } else { "of at least 0," };
match v {
Value::Int(i) => *i,
Value::Float(f) => panic!("{} must be a whole number {} received {}", what, rule, f),
_ => panic!("{} must be a whole number {}", what, rule),
}
}
pub fn fune_vector(args: &[Value]) -> Value {
Value::Int(burn_rate(
whole(&args[0], "targetBasisPoints"),
whole(&args[1], "totalEvents"),
whole(&args[2], "badEvents"),
))
}