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, parse_iso_date}; ← 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
/// The day the given number of months is completed. add_months clamps 31
/// January + 1 month to 28 February; a clamped day has not yet reached the
/// birth day, so the month completes the day after it (1 March), the same rule
/// dates.age uses for a 29 February birthday.
fn month_anniversary(birth_date: &str, birth_day: i64, months: i64) -> String {
let shifted = add_months(birth_date, months);
if parse_iso_date(&shifted).day < birth_day {
add_days(&shifted, 1)
} else {
shifted
}
}
/// Completed months and remaining days from `birth_date` to `on_date`.
///
/// # Panics
/// Panics on a malformed or impossible date, or `on_date` before `birth_date`.
pub fn age_in_months(birth_date: &str, on_date: &str) -> AgeInMonths {
let birth = parse_iso_date(birth_date);
let on = parse_iso_date(on_date);
if on_date < birth_date {
panic!("onDate {} is before birthDate {}", on_date, birth_date);
}
let mut months = (on.year - birth.year) * 12 + (on.month - birth.month);
let mut anniversary = month_anniversary(birth_date, birth.day, months);
if anniversary.as_str() > on_date {
months -= 1;
anniversary = month_anniversary(birth_date, birth.day, months);
}
AgeInMonths {
months,
days: days_between(&anniversary, on_date),
total_days: days_between(birth_date, on_date),
}
}
pub fn age_in_months_to_value(age: &AgeInMonths) -> Value {
Value::obj(vec![
("months", Value::Int(age.months)),
("days", Value::Int(age.days)),
("totalDays", Value::Int(age.total_days)),
])
}
fn date_arg(value: &Value) -> &str {
match value {
Value::Str(s) => s.as_str(),
_ => panic!("{:?} is not an ISO date (YYYY-MM-DD)", value),
}
}
pub fn fune_vector(args: &[Value]) -> Value {
age_in_months_to_value(&age_in_months(date_arg(&args[0]), date_arg(&args[1])))
}