math-mumu 0.1.0

Math functions plugin for the Mumu / Lava language
Documentation
use mumu::parser::interpreter::Interpreter;
use mumu::parser::types::Value;
use rust_decimal::Decimal;
use rust_decimal::prelude::{FromStr, ToPrimitive};

/// Basic bridging for `math:sqrt(...)`.
/// - Single numeric argument => returns float
/// - If negative => error
pub fn math_sqrt_bridge(_i: &mut Interpreter, mut args: Vec<Value>) -> Result<Value, String> {
    if args.len() != 1 {
        return Err(format!("math:sqrt => expected 1 argument, got {}", args.len()));
    }
    let val = args.remove(0);
    let ff = coerce_to_f64(val)?;
    if ff < 0.0 {
        return Err(format!("math:sqrt => cannot sqrt negative => {}", ff));
    }
    Ok(Value::Float(ff.sqrt()))
}

fn coerce_to_f64(v: Value) -> Result<f64, String> {
    match v {
        Value::Int(i) => Ok(i as f64),
        Value::Long(l) => Ok(l as f64),
        Value::Float(ff) => Ok(ff),
        Value::SingleString(s) => {
            let dec = Decimal::from_str(&s)
                .map_err(|e| format!("Cannot parse '{}' => {}", s, e))?;
            // `.to_f64()` requires `ToPrimitive` in scope
            Ok(dec.to_f64().unwrap_or(0.0))
        }
        _ => Err(format!("math:sqrt => argument must be numeric or parseable, got {:?}", v)),
    }
}