Functional Weave
Code in TypeScript

inventory.reorder-point@1.0.0

impl/rust.rs

1,475 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
use super::math_round_div::round_div;  ← from math.round-div ^1.0.0 · built alongside by fune

fn whole_units(name: &str, value: i64) {
    if value < 0 {
        panic!("{} must be a whole number, not negative, received {}", name, value);
    }
}

/// Lead-time demand, rounded up to whole units, plus safety stock.
///
/// Rounding up rather than to nearest: 233.33 units of lead-time demand needs
/// 234 in hand, or the last third of a unit is a stock-out.
///
/// # Panics
/// Panics on a negative input or a demand period of less than one day.
pub fn reorder_point(demand: i64, demand_period_days: i64, lead_time_days: i64, safety_stock: i64) -> i64 {
    whole_units("demand", demand);
    whole_units("leadTimeDays", lead_time_days);
    whole_units("safetyStock", safety_stock);
    if demand_period_days <= 0 {
        panic!(
            "demandPeriodDays must be a whole number of days, at least 1, received {}",
            demand_period_days
        );
    }
    round_div(demand * lead_time_days, demand_period_days, "up") + safety_stock
}

pub fn fune_vector(args: &[Value]) -> Value {
    let names = ["demand", "demandPeriodDays", "leadTimeDays", "safetyStock"];
    for (i, name) in names.iter().enumerate() {
        if let Value::Float(f) = &args[i] {
            panic!("{} must be a whole number, received {}", name, f);
        }
    }
    Value::Int(reorder_point(
        args[0].as_i64(),
        args[1].as_i64(),
        args[2].as_i64(),
        args[3].as_i64(),
    ))
}