use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct CalendarConfig {
pub week_start: u32,
pub fiscal_year_start: u32,
pub fiscal_quarter_start: u32,
pub holidays: HashMap<i32, Vec<(u32, u32)>>,
}
impl Default for CalendarConfig {
fn default() -> Self {
Self {
week_start: 0, fiscal_year_start: 1, fiscal_quarter_start: 1, holidays: HashMap::new(),
}
}
}
impl CalendarConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_week_start(mut self, day: u32) -> Self {
self.week_start = day % 7;
self
}
pub fn with_fiscal_year_start(mut self, month: u32) -> Self {
self.fiscal_year_start = month.clamp(1, 12);
self
}
pub fn with_fiscal_quarter_start(mut self, month: u32) -> Self {
self.fiscal_quarter_start = month.clamp(1, 12);
self
}
pub fn add_holiday(mut self, year: i32, month: u32, day: u32) -> Self {
self.holidays
.entry(year)
.or_insert_with(Vec::new)
.push((month, day));
self
}
pub fn add_holidays(mut self, year: i32, holidays: &[(u32, u32)]) -> Self {
self.holidays
.entry(year)
.or_insert_with(Vec::new)
.extend_from_slice(holidays);
self
}
pub fn is_holiday(&self, year: i32, month: u32, day: u32) -> bool {
self.holidays
.get(&year)
.map(|h| h.contains(&(month, day)))
.unwrap_or(false)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = CalendarConfig::default();
assert_eq!(config.week_start, 0); assert_eq!(config.fiscal_year_start, 1); assert_eq!(config.fiscal_quarter_start, 1);
}
#[test]
fn test_with_week_start() {
let config = CalendarConfig::new().with_week_start(6); assert_eq!(config.week_start, 6);
}
#[test]
fn test_with_fiscal_year() {
let config = CalendarConfig::new().with_fiscal_year_start(7); assert_eq!(config.fiscal_year_start, 7);
}
#[test]
fn test_add_holiday() {
let config = CalendarConfig::new().add_holiday(2024, 12, 25); assert!(config.is_holiday(2024, 12, 25));
assert!(!config.is_holiday(2024, 12, 26));
}
#[test]
fn test_add_holidays() {
let holidays = vec![(1, 1), (7, 4), (12, 25)]; let config = CalendarConfig::new().add_holidays(2024, &holidays);
assert!(config.is_holiday(2024, 1, 1));
assert!(config.is_holiday(2024, 7, 4));
assert!(config.is_holiday(2024, 12, 25));
assert!(!config.is_holiday(2024, 6, 15));
}
#[test]
fn test_is_holiday_different_year() {
let config = CalendarConfig::new().add_holiday(2024, 12, 25);
assert!(config.is_holiday(2024, 12, 25));
assert!(!config.is_holiday(2025, 12, 25)); }
}