use crate::DayFlags;
use crate::raw_date::RawDate;
pub(crate) use masks::MonthMasks;
pub(crate) use masks::days;
pub(crate) use months_macro::months;
mod federal;
mod masks;
mod months_macro;
pub(crate) mod regional;
pub(crate) const FACT_FIRST_YEAR: i32 = federal::FACT_FIRST_YEAR;
pub(crate) const FACT_LAST_YEAR: i32 = federal::FACT_LAST_YEAR;
pub(crate) const FEDERAL_HOLIDAYS: MonthMasks = months! {
Jan: [1, 2, 3, 4, 5, 6, 7, 8],
Feb: [23],
Mar: [8],
May: [1, 9],
Jun: [12],
Nov: [4],
};
pub(crate) const NON_JANUARY_HOLIDAYS: [MonthDay; 6] = [
MonthDay::new(2, 23),
MonthDay::new(3, 8),
MonthDay::new(5, 1),
MonthDay::new(5, 9),
MonthDay::new(6, 12),
MonthDay::new(11, 4),
];
#[derive(Debug, Clone, Copy)]
pub(crate) struct YearFact {
pub holidays: MonthMasks,
pub extra_days_off: MonthMasks,
pub working_days: MonthMasks,
pub short_days: MonthMasks,
pub transferred_days: MonthMasks,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct MonthDay {
pub month: u8,
pub day: u8,
}
impl MonthDay {
#[inline]
pub(crate) const fn new(month: u8, day: u8) -> Self {
Self { month, day }
}
}
#[inline]
pub(crate) fn fact_year(year: i32) -> Option<&'static YearFact> {
federal::fact_year(year)
}
#[inline]
pub(crate) fn flags_from_year_fact(fact: &YearFact, date: RawDate) -> DayFlags {
let month = date.month;
let day = date.day;
let weekend = date.weekday >= 5;
let holiday = fact.holidays.contains(month, day);
let extra_day_off = fact.extra_days_off.contains(month, day);
let working_day_override = fact.working_days.contains(month, day);
let short_day = fact.short_days.contains(month, day);
let transferred = fact.transferred_days.contains(month, day);
let day_off = !working_day_override && (weekend || holiday || extra_day_off);
let working_day = !day_off;
DayFlags::EMPTY
.with_if(weekend, DayFlags::WEEKEND)
.with_if(holiday, DayFlags::HOLIDAY)
.with_if(day_off, DayFlags::DAY_OFF)
.with_if(working_day, DayFlags::WORKING_DAY)
.with_if(short_day, DayFlags::SHORT_DAY)
.with_if(transferred, DayFlags::TRANSFERRED)
}
#[inline]
pub(crate) fn flags_from_regional_year_fact(fact: &YearFact, date: RawDate) -> DayFlags {
let month = date.month;
let day = date.day;
let holiday = fact.holidays.contains(month, day);
let extra_day_off = fact.extra_days_off.contains(month, day);
let short_day = fact.short_days.contains(month, day);
let transferred = fact.transferred_days.contains(month, day);
DayFlags::EMPTY
.with_if(holiday, DayFlags::HOLIDAY)
.with_if(holiday || extra_day_off, DayFlags::DAY_OFF)
.with_if(short_day, DayFlags::SHORT_DAY)
.with_if(transferred, DayFlags::TRANSFERRED)
}