Functional Weave
Code in TypeScript

hr.length-of-service@1.0.0

impl/rust.rs

1,714 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::{add_days, days_between};  ← from dates.add-days ^1.0.0 · built alongside by fune
use super::dates_add_months::add_months;  ← from dates.add-months ^1.0.0 · built alongside by fune

/// Completed years, months and days of service, both end dates included.
///
/// The end is moved to the following day so that a service period ending on
/// the eve of an anniversary counts as a whole year; forgetting that is the
/// off-by-one that denies someone a statutory right by a day.
///
/// # Panics
/// Panics on a malformed date or an end before the start.
pub fn length_of_service(start_date: &str, end_date: &str) -> ServiceLength {
    let total_days = days_between(start_date, end_date) + 1;
    if total_days < 1 {
        panic!("endDate {} is before startDate {}", end_date, start_date);
    }
    let end_exclusive = add_days(end_date, 1);
    let num = |s: &str, a: usize, b: usize| s[a..b].parse::<i64>().unwrap();
    let mut months = (num(&end_exclusive, 0, 4) - num(start_date, 0, 4)) * 12
        + (num(&end_exclusive, 5, 7) - num(start_date, 5, 7));
    while months > 0 && add_months(start_date, months) > end_exclusive {
        months -= 1;
    }
    let anniversary = add_months(start_date, months);
    ServiceLength {
        years: months / 12,
        months: months % 12,
        days: days_between(&anniversary, &end_exclusive),
        total_days,
    }
}

pub fn service_length_to_value(s: &ServiceLength) -> Value {
    Value::obj(vec![
        ("years", Value::Int(s.years)),
        ("months", Value::Int(s.months)),
        ("days", Value::Int(s.days)),
        ("totalDays", Value::Int(s.total_days)),
    ])
}

pub fn fune_vector(args: &[Value]) -> Value {
    service_length_to_value(&length_of_service(args[0].as_str(), args[1].as_str()))
}