use crate::checker::{OriginalHolidayChecker, compute_holidays};
use crate::date::Date;
use crate::model::Holiday;
use crate::registry::HolidayCheckerRegistry;
use std::cell::RefCell;
use std::collections::HashMap;
pub struct JPHoliday {
registry: HolidayCheckerRegistry,
cache: RefCell<HashMap<Date, Vec<Holiday>>>,
}
impl JPHoliday {
pub fn new() -> Self {
JPHoliday {
registry: HolidayCheckerRegistry::new(),
cache: RefCell::new(HashMap::new()),
}
}
pub fn holidays(&self, date: Date) -> Vec<Holiday> {
if let Some(cached) = self.cache.borrow().get(&date) {
return cached.clone();
}
let result = compute_holidays(self.registry.checkers(), date);
self.cache.borrow_mut().insert(date, result.clone());
result
}
pub fn is_holiday(&self, date: Date) -> bool {
!self.holidays(date).is_empty()
}
pub fn is_holiday_name(&self, date: Date) -> Option<String> {
self.holidays(date).into_iter().next().map(|h| h.name)
}
pub fn year_holidays(&self, year: i32) -> Vec<Holiday> {
let mut out = Vec::new();
let mut date = Date::new(year, 1, 1).expect("January 1st is always a valid date");
while date.year() == year {
out.extend(self.holidays(date));
date = date.succ();
}
out
}
pub fn month_holidays(&self, year: i32, month: u32) -> Vec<Holiday> {
let mut out = Vec::new();
let mut date = match Date::new(year, month, 1) {
Ok(d) => d,
Err(_) => return out,
};
while date.month() == month {
out.extend(self.holidays(date));
date = date.succ();
}
out
}
pub fn between(&self, start: Date, end: Date) -> Vec<Holiday> {
let mut out = Vec::new();
let mut current = start;
while current <= end {
out.extend(self.holidays(current));
current = current.succ();
}
out
}
pub fn register<C: OriginalHolidayChecker + 'static>(&mut self, checker: C) {
self.cache.borrow_mut().clear();
self.registry.register(checker);
}
pub fn unregister<C: OriginalHolidayChecker + 'static>(&mut self) {
self.cache.borrow_mut().clear();
self.registry.unregister::<C>();
}
}
impl Default for JPHoliday {
fn default() -> Self {
Self::new()
}
}