use super::funejson::Value; use super::dates_bank_holidays_data::BANK_HOLIDAYS; /// The bank holidays for a UK region and year, in date order, as gov.uk /// publishes them. A year the data does not cover is an error rather than an /// empty list, because an empty list reads as "no holidays" and a deadline /// calculation would then count Christmas Day as a working day. /// /// # Panics /// Panics on an unknown region or a year outside the published calendar. pub fn bank_holidays(region: &str, year: i64) -> Vec { let mut first: Option = None; let mut last: Option = None; let mut found: Vec = Vec::new(); let prefix = format!("{:04}-", year); for row in BANK_HOLIDAYS { if row.region != region { continue; } let row_year: i64 = row.date[0..4].parse().unwrap(); if first.map_or(true, |f| row_year < f) { first = Some(row_year); } if last.map_or(true, |l| row_year > l) { last = Some(row_year); } if row.date.starts_with(&prefix) { found.push(BankHoliday { date: row.date.to_string(), title: row.title.to_string(), substitute: row.substitute, }); } } let (first, last) = match (first, last) { (Some(f), Some(l)) => (f, l), _ => panic!( "unknown region \"{}\": expected england-and-wales, scotland or northern-ireland", region ), }; if year < first || year > last { panic!( "no bank holiday data for {} in {}: the published calendar covers {} to {}", region, year, first, last ); } // ISO dates sort correctly as strings. found.sort_by(|a, b| a.date.cmp(&b.date)); found } pub fn bank_holiday_to_value(holiday: &BankHoliday) -> Value { Value::obj(vec![ ("date", Value::str(&holiday.date)), ("title", Value::str(&holiday.title)), ("substitute", Value::Bool(holiday.substitute)), ]) } pub fn fune_vector(args: &[Value]) -> Value { // Refuse what the typed signature cannot hold, with the wording TypeScript // and Python use, rather than let the conversion below quietly change it. if let Value::Float(f) = args[1] { if f.fract() != 0.0 { panic!("year must be an integer, received {}", f); } } Value::Arr( bank_holidays(args[0].as_str(), args[1].as_i64()) .iter() .map(bank_holiday_to_value) .collect(), ) }