Functional Weave
Code in TypeScript

manufacturing.lot-number@1.0.0

impl/rust.rs

1,372 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::dates_add_days::{days_from_civil, parse_iso_date};  ← from dates.add-days ^1.0.0 · built alongside by fune

/// Lot code YYDDD-LL-SSS: two-digit year, day of the year, line, sequence.
///
/// The day of the year counts from the epoch-day kernel in dates.add-days, so
/// leap years move every date after 28 February without a month table.
///
/// # Panics
/// Panics on a line outside 1-99, a sequence outside 1-999, or a bad date.
pub fn lot_number(production_date: &str, line: i64, sequence: i64) -> String {
    if !(1..=99).contains(&line) {
        panic!("line must be a whole number from 1 to 99, received {}", line);
    }
    if !(1..=999).contains(&sequence) {
        panic!("sequence must be a whole number from 1 to 999, received {}", sequence);
    }
    let date = parse_iso_date(production_date);
    let day_of_year = days_from_civil(date.year, date.month, date.day) - days_from_civil(date.year, 1, 1) + 1;
    format!("{:02}{:03}-{:02}-{:03}", date.year % 100, day_of_year, line, sequence)
}

pub fn fune_vector(args: &[Value]) -> Value {
    if let Value::Float(f) = &args[1] {
        panic!("line must be a whole number from 1 to 99, received {}", f);
    }
    if let Value::Float(f) = &args[2] {
        panic!("sequence must be a whole number from 1 to 999, received {}", f);
    }
    Value::Str(lot_number(args[0].as_str(), args[1].as_i64(), args[2].as_i64()))
}