Functional Weave
Code in TypeScript

dates.week-number@1.0.0

impl/rust.rs

1,149 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::{civil_from_days, days_from_civil, epoch_day_from_iso};  ← from dates.add-days ^1.0.0 · built alongside by fune
use super::dates_day_of_week::day_of_week;  ← from dates.day-of-week ^1.0.0 · built alongside by fune

/// The ISO 8601 week of a date. The Thursday of the date's Monday-to-Sunday
/// week decides everything: its calendar year is the week-year, and its day of
/// that year gives the week number.
///
/// # Panics
/// Panics if the date is malformed or impossible.
pub fn week_number(iso: &str) -> IsoWeek {
    let thursday = epoch_day_from_iso(iso) + (4 - day_of_week(iso));
    let week_year = civil_from_days(thursday).year;
    // Non-negative: the Thursday is never before 1 January of its own year.
    let week = (thursday - days_from_civil(week_year, 1, 1)) / 7 + 1;
    IsoWeek {
        week_year,
        week,
        label: format!("{:04}-W{:02}", week_year, week),
    }
}

pub fn iso_week_to_value(w: &IsoWeek) -> Value {
    Value::obj(vec![
        ("weekYear", Value::Int(w.week_year)),
        ("week", Value::Int(w.week)),
        ("label", Value::str(&w.label)),
    ])
}

pub fn fune_vector(args: &[Value]) -> Value {
    iso_week_to_value(&week_number(args[0].as_str()))
}