rave_engine 0.8.0

A secure and efficient JSON Schema validation and Rhai script execution engine
Documentation
//! Locks the `to_num` host fn's contract through the real engine: agreements
//! read *authored* numeric fields (price-sheet rates, invoice log counts,
//! runtime inputs) whose JSON shape the author controls — a number or a
//! numeric string must both dispatch, and garbage must fail the run loudly,
//! never collapse to a silent 0 (a free service, in a price sheet).

use crate::rhai_engine::{RhaiEngine, RhaiEngineConfig};
use serde_json::json;

fn engine() -> RhaiEngine {
    RhaiEngine::with_config(RhaiEngineConfig::default().with_use_holochain_time(false)).unwrap()
}

#[test]
fn to_num_dispatches_on_both_authored_shapes() {
    // rate authored as a string, count as a number — the exact mixed pair the
    // holo-hosting agreement reads (price sheet vs invoice logs).
    let script = rmp_serde::to_vec(
        &r#"
        let total = to_num(inputs.rate.data) * to_num(inputs.count.data);
        if total != 3.0 { throw "wrong total: " + total.to_string() }
        #{ "output": #{ "unyt_allocation": [] } }
    "#,
    )
    .unwrap();
    let input = json!({ "inputs": { "rate": { "data": "0.5" }, "count": { "data": 6 } } });
    engine()
        .execute(&input, script, None)
        .expect("both authored shapes must dispatch through to_num");
}

#[test]
fn to_num_garbage_fails_the_run_naming_the_value() {
    let script =
        rmp_serde::to_vec(&r#" #{ "output": #{ "x": to_num(inputs.rate.data) } } "#).unwrap();
    let input = json!({ "inputs": { "rate": { "data": "O.5" } } });
    let err = format!(
        "{:?}",
        engine()
            .execute(&input, script, None)
            .expect_err("a typo'd rate must refuse the run, not price it at 0")
    );
    assert!(err.contains("O.5"), "the error must name the value: {err}");
}