Functional Weave
Code in Rust

dates.overlap@1.0.0

impl/rust.rs

1,238 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

/// Days two ranges have in common. `end_inclusive` says whether each end date
/// is the range's last day (a statement period) or the day after it (a
/// half-open range, a hotel stay); both ranges use the same convention.
///
/// # Panics
/// Panics on a malformed date or a range that ends before it starts.
pub fn overlap_days(a_start: &str, a_end: &str, b_start: &str, b_end: &str, end_inclusive: bool) -> i64 {
    let a0 = epoch_day_from_iso(a_start);
    let a1 = epoch_day_from_iso(a_end);
    let b0 = epoch_day_from_iso(b_start);
    let b1 = epoch_day_from_iso(b_end);
    if a1 < a0 {
        panic!("range A starts {}, after its end {}", a_start, a_end);
    }
    if b1 < b0 {
        panic!("range B starts {}, after its end {}", b_start, b_end);
    }
    // An inclusive end is the half-open end one day later.
    let extra = if end_inclusive { 1 } else { 0 };
    let days = a1.min(b1) + extra - a0.max(b0);
    days.max(0)
}

pub fn fune_vector(args: &[Value]) -> Value {
    Value::Int(overlap_days(
        args[0].as_str(),
        args[1].as_str(),
        args[2].as_str(),
        args[3].as_str(),
        args[4].as_bool(),
    ))
}