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_bank_holidays::bank_holidays; ← from dates.bank-holidays ^1.0.0 · built alongside by fune
use super::dates_day_of_week::is_weekday; ← from dates.day-of-week ^1.0.0 · built alongside by fune
fn holidays_for(years: &[i64]) -> Vec<String> {
let mut out = Vec::new();
for year in years {
for holiday in bank_holidays("england-and-wales", *year) {
out.push(holiday.date);
}
}
out
}
fn cycle_with(submission_iso: &str, after_cutoff: bool, holidays: &[String]) -> BacsCycle {
let processing_day = is_weekday(submission_iso) && !holidays.iter().any(|h| h == submission_iso);
let input_day = if processing_day && !after_cutoff {
submission_iso.to_string()
} else {
add_business_days(submission_iso, 1, holidays)
};
BacsCycle {
processing_day: add_business_days(&input_day, 1, holidays),
entry_day: add_business_days(&input_day, 2, holidays),
input_day,
}
}
/// The Bacs cycle a file joins. Bacs works on processing days - Monday to
/// Friday except England and Wales bank holidays - and a file joins the cycle
/// whose input day is the day it arrives, if that is a processing day and it
/// arrived before the 22:30 deadline, or the next processing day otherwise.
/// Processing is the next processing day and entry the one after.
///
/// # Panics
/// Panics on a malformed date or a year outside the published holiday data.
pub fn bacs_processing_dates(submission_iso: &str, after_cutoff: bool) -> BacsCycle {
// is_weekday validates the date before its year is read.
is_weekday(submission_iso);
let year: i64 = submission_iso[0..4].parse().unwrap();
// Only reach for next year's calendar when the cycle really runs into it,
// so a December submission in the last published year still works as long
// as its cycle ends inside that year.
let mut cycle = cycle_with(submission_iso, after_cutoff, &holidays_for(&[year]));
if cycle.entry_day[0..4] != submission_iso[0..4] {
cycle = cycle_with(submission_iso, after_cutoff, &holidays_for(&[year, year + 1]));
}
cycle
}
pub fn bacs_cycle_to_value(cycle: &BacsCycle) -> Value {
Value::obj(vec![
("inputDay", Value::str(&cycle.input_day)),
("processingDay", Value::str(&cycle.processing_day)),
("entryDay", Value::str(&cycle.entry_day)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
bacs_cycle_to_value(&bacs_processing_dates(args[0].as_str(), args[1].as_bool()))
}