(name: &str, args: &[Value])
| 7 | use nodedb_types::Value; |
| 8 | |
| 9 | pub(super) fn try_eval(name: &str, args: &[Value]) -> Option<Value> { |
| 10 | let v = match name { |
| 11 | "abs" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.abs())), |
| 12 | "round" => { |
| 13 | let Some(n) = num_arg(args, 0) else { |
| 14 | return Some(Value::Null); |
| 15 | }; |
| 16 | let decimals = num_arg(args, 1).unwrap_or(0.0) as u32; |
| 17 | let mode_str = super::shared::str_arg(args, 2).unwrap_or_default(); |
| 18 | let strategy = match mode_str.to_uppercase().as_str() { |
| 19 | "HALF_UP" => rust_decimal::RoundingStrategy::MidpointAwayFromZero, |
| 20 | "HALF_DOWN" => rust_decimal::RoundingStrategy::MidpointTowardZero, |
| 21 | "TRUNCATE" | "TRUNC" => rust_decimal::RoundingStrategy::ToZero, |
| 22 | "CEILING" | "CEIL" => rust_decimal::RoundingStrategy::AwayFromZero, |
| 23 | "FLOOR" => rust_decimal::RoundingStrategy::ToNegativeInfinity, |
| 24 | _ => rust_decimal::RoundingStrategy::MidpointNearestEven, |
| 25 | }; |
| 26 | match rust_decimal::Decimal::try_from(n) { |
| 27 | Ok(d) => { |
| 28 | let rounded = d.round_dp_with_strategy(decimals, strategy); |
| 29 | use rust_decimal::prelude::ToPrimitive; |
| 30 | rounded.to_f64().map_or(Value::Null, to_value_number) |
| 31 | } |
| 32 | Err(_) => Value::Null, |
| 33 | } |
| 34 | } |
| 35 | "ceil" | "ceiling" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.ceil())), |
| 36 | "floor" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.floor())), |
| 37 | "power" | "pow" => { |
| 38 | let Some(base) = num_arg(args, 0) else { |
| 39 | return Some(Value::Null); |
| 40 | }; |
| 41 | let exp = num_arg(args, 1).unwrap_or(1.0); |
| 42 | to_value_number(base.powf(exp)) |
| 43 | } |
| 44 | "sqrt" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.sqrt())), |
| 45 | "mod" => { |
| 46 | let Some(a) = num_arg(args, 0) else { |
| 47 | return Some(Value::Null); |
| 48 | }; |
| 49 | let b = num_arg(args, 1).unwrap_or(1.0); |
| 50 | if b == 0.0 { |
| 51 | Value::Null |
| 52 | } else { |
| 53 | to_value_number(a % b) |
| 54 | } |
| 55 | } |
| 56 | "sign" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.signum())), |
| 57 | "log" | "ln" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.ln())), |
| 58 | "log10" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.log10())), |
| 59 | "log2" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.log2())), |
| 60 | "exp" => num_arg(args, 0).map_or(Value::Null, |n| to_value_number(n.exp())), |
| 61 | _ => return None, |
| 62 | }; |
| 63 | Some(v) |
| 64 | } |
nothing calls this directly
no test coverage detected