Functional Weave
Code in Rust

dates.day-of-week@1.0.0

impl/rust.rs

1,493 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::epoch_day_from_iso;  ← from dates.add-days ^1.0.0 · built alongside by fune

pub const DAY_NAMES: [&str; 7] = [
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday",
];

/// The ISO 8601 day of the week: 1 = Monday through 7 = Sunday.
///
/// ISO numbering because it is what the rest of the business world means by
/// "day 1", and because a weekend test is then `day >= 6` in every language.
///
/// # Panics
/// Panics if the date is malformed or impossible.
pub fn day_of_week(iso: &str) -> i64 {
    // 1970-01-01, epoch day 0, was a Thursday. Shifting by 3 moves the origin of
    // the cycle to Monday so that the remainder is already ISO numbering.
    // rem_euclid, not %, because dates before 1970 have negative day numbers and
    // Rust's % keeps the sign of the dividend.
    (epoch_day_from_iso(iso) + 3).rem_euclid(7) + 1
}

/// True for Saturday and Sunday.
pub fn is_weekend(iso: &str) -> bool {
    day_of_week(iso) >= 6
}

/// True for Monday to Friday. Says nothing about public holidays.
pub fn is_weekday(iso: &str) -> bool {
    day_of_week(iso) <= 5
}

/// The English name, for logs and labels. Not localised, deliberately: a
/// capability that needed locale data would need a locale argument and a data
/// file to pin it.
pub fn day_name(iso: &str) -> &'static str {
    DAY_NAMES[(day_of_week(iso) - 1) as usize]
}

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