Functional Weave
Code in Rust

energy.meter-advance@1.0.0

impl/rust.rs

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

/// Units a meter advanced between two reads. A closing read lower than the
/// opening read means the register rolled over past all nines, once.
///
/// # Panics
/// Panics if `digits` is outside 1 to 15, or a read does not fit the register.
pub fn meter_advance(opening_read: i64, closing_read: i64, digits: i64) -> i64 {
    if !(1..=15).contains(&digits) {
        panic!("digits must be a whole number from 1 to 15, received {}", digits);
    }
    let span = 10_i64.pow(digits as u32);
    for read in [opening_read, closing_read] {
        if read < 0 || read >= span {
            panic!(
                "reads must be whole numbers from 0 to {} for a {}-digit meter, received {}",
                span - 1,
                digits,
                read
            );
        }
    }
    if closing_read >= opening_read {
        closing_read - opening_read
    } else {
        closing_read + span - opening_read
    }
}

pub fn fune_vector(args: &[Value]) -> Value {
    for arg in &args[0..2] {
        if let Value::Float(f) = arg {
            panic!("reads must be whole numbers, received {}", f);
        }
    }
    Value::Int(meter_advance(args[0].as_i64(), args[1].as_i64(), args[2].as_i64()))
}