Functional Weave
Code in Rust

subscriptions.dunning-schedule@1.0.0

impl/rust.rs

1,735 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_business_days::add_business_days;  ← from dates.add-business-days ^1.0.0 · built alongside by fune
use super::dates_add_days::add_days;  ← from dates.add-days ^1.0.0 · built alongside by fune

/// The retry dates for a payment that failed on `failed_on`. Each offset
/// counts from the failure date, not from the previous retry, in calendar days
/// or in working days.
///
/// # Panics
/// Panics if an offset is below 1 or not above the one before, or a date is
/// not a real ISO date.
pub fn dunning_schedule(failed_on: &str, retry_offsets_days: &[i64], business_days: bool, holidays: &[String]) -> Vec<String> {
    let mut previous = 0;
    for &offset in retry_offsets_days {
        if offset < 1 {
            panic!("retry offsets must be whole days of 1 or more, received {}", offset);
        }
        if offset <= previous {
            panic!(
                "retry offsets must be strictly increasing, received {} after {}",
                offset, previous
            );
        }
        previous = offset;
    }
    // Validates the failure date even for an empty policy.
    add_days(failed_on, 0);
    retry_offsets_days
        .iter()
        .map(|&offset| {
            if business_days {
                add_business_days(failed_on, offset, holidays)
            } else {
                add_days(failed_on, offset)
            }
        })
        .collect()
}

pub fn fune_vector(args: &[Value]) -> Value {
    let offsets: Vec<i64> = args[1].as_arr().iter().map(|v| v.as_i64()).collect();
    let holidays: Vec<String> = args[3].as_arr().iter().map(|v| v.as_str().to_string()).collect();
    Value::Arr(
        dunning_schedule(args[0].as_str(), &offsets, args[2].as_bool(), &holidays)
            .iter()
            .map(|d| Value::str(d))
            .collect(),
    )
}