api changes
This commit is contained in:
		
							parent
							
								
									d82ef99c55
								
							
						
					
					
						commit
						8a78e8f901
					
				@ -4,6 +4,15 @@ version = "0.1.1"
 | 
			
		||||
edition = "2024"
 | 
			
		||||
publish = ["kellnr"]
 | 
			
		||||
 | 
			
		||||
# [features]
 | 
			
		||||
# default = ["de"]
 | 
			
		||||
# # Includes Germany
 | 
			
		||||
# de = []
 | 
			
		||||
# # Includes France
 | 
			
		||||
# fr = []
 | 
			
		||||
# # Includes The United States
 | 
			
		||||
# us = []
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
time = "0.3.41"
 | 
			
		||||
strum = { version = "0.27.2", features = ["derive"] }
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
use time::{Date, Duration, Month, Weekday};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    countries::{CountryHolidays, StateList},
 | 
			
		||||
    countries::StateList,
 | 
			
		||||
    holiday::{Activity, HDate, Holiday},
 | 
			
		||||
    utils::{self},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(super) struct GermanHolidays;
 | 
			
		||||
pub(crate) struct GermanHolidays(pub Vec<Holiday<GermanState>>);
 | 
			
		||||
 | 
			
		||||
#[derive(strum::Display, Hash, PartialEq, Eq)]
 | 
			
		||||
#[derive(Debug, strum::Display, Clone, Copy, Hash, PartialEq, Eq)]
 | 
			
		||||
pub enum GermanState {
 | 
			
		||||
    /// Baden-Württemberg
 | 
			
		||||
    BW,
 | 
			
		||||
@ -52,164 +52,162 @@ impl super::StateList for GermanState {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl CountryHolidays<GermanState> for GermanHolidays {
 | 
			
		||||
    fn new() -> (String, Vec<Holiday>) {
 | 
			
		||||
impl GermanHolidays {
 | 
			
		||||
    pub(crate) fn new() -> Self {
 | 
			
		||||
        use GermanState::*;
 | 
			
		||||
        use time::Month::*;
 | 
			
		||||
        (
 | 
			
		||||
            GermanState::all_states_identifier(),
 | 
			
		||||
            vec![
 | 
			
		||||
                // New Years Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Neujahrstag".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(January, 1),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Epiphany
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Heilige drei Könige".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(January, 6),
 | 
			
		||||
                    states: GermanState::list(&[
 | 
			
		||||
                        (BW, &[Activity::after(1990)]),
 | 
			
		||||
                        (BY, &[Activity::after(1990)]),
 | 
			
		||||
                        (ST, &[Activity::after(1990)]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // International Women's Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Internationaler Frauentag".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(March, 8),
 | 
			
		||||
                    states: GermanState::list(&[
 | 
			
		||||
                        (BE, &[Activity::after(2019)]),
 | 
			
		||||
                        (MV, &[Activity::after(2023)]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // Good Friday
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Karfreitag".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::easter_monday(year) - Duration::days(3)),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Easter Monday
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Ostermontag".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(utils::easter_monday),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Labour Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Tag der Arbeit".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(May, 1),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Ascension Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Christi Himmelfahrt".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(38)),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Whit Monday
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Pfingstmontag".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(49)),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Corpus Christi
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Fronleichnam".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(59)),
 | 
			
		||||
                    states: GermanState::list(&[
 | 
			
		||||
                        (BW, &[Activity::after(1990)]),
 | 
			
		||||
                        (BY, &[Activity::after(1990)]),
 | 
			
		||||
                        (HE, &[Activity::after(1990)]),
 | 
			
		||||
                        (NW, &[Activity::after(1990)]),
 | 
			
		||||
                        (RP, &[Activity::after(1990)]),
 | 
			
		||||
                        (SL, &[Activity::after(1990)]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // Assumption Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Mariä Himmelfahrt".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(August, 15),
 | 
			
		||||
                    states: GermanState::list(&[
 | 
			
		||||
                        (BY, &[Activity::after(1990)]),
 | 
			
		||||
                        (SL, &[Activity::after(1990)]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // World Children's Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Weltkindertag".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(September, 20),
 | 
			
		||||
                    states: GermanState::list(&[(TH, &[Activity::after(2019)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // German Unity Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Tag der Deutschen Einheit".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(October, 3),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Reformation Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Reformationstag".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(October, 31),
 | 
			
		||||
                    states: GermanState::list(&[
 | 
			
		||||
                        (ANY, &[Activity::range(2017, 2017)]),
 | 
			
		||||
                        (BB, &[Activity::after(1990)]),
 | 
			
		||||
                        (MV, &[Activity::after(1990)]),
 | 
			
		||||
                        (SN, &[Activity::after(1990)]),
 | 
			
		||||
                        (ST, &[Activity::after(1990)]),
 | 
			
		||||
                        (TH, &[Activity::after(1990)]),
 | 
			
		||||
                        (HB, &[Activity::after(2018)]),
 | 
			
		||||
                        (HH, &[Activity::after(2018)]),
 | 
			
		||||
                        (NI, &[Activity::after(2018)]),
 | 
			
		||||
                        (SH, &[Activity::after(2018)]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // All Saints Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Allerheiligen".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(November, 1),
 | 
			
		||||
                    states: GermanState::list(&[
 | 
			
		||||
                        (BW, &[Activity::after(1990)]),
 | 
			
		||||
                        (BY, &[Activity::after(1990)]),
 | 
			
		||||
                        (NW, &[Activity::after(1990)]),
 | 
			
		||||
                        (RP, &[Activity::after(1990)]),
 | 
			
		||||
                        (SL, &[Activity::after(1990)]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // Repentance And Prayer Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Buß- und Bettag".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| {
 | 
			
		||||
                        //	Der Buß- und Bettag ist immer ein Mittwoch, er liegt zwischen dem 16. und 22. November
 | 
			
		||||
                        let november_22 = Date::from_calendar_date(year, Month::November, 22)
 | 
			
		||||
                            .expect("22 Nov should exist every year");
 | 
			
		||||
 | 
			
		||||
                        if november_22.weekday() == Weekday::Wednesday {
 | 
			
		||||
                            november_22
 | 
			
		||||
                        } else {
 | 
			
		||||
                            november_22.prev_occurrence(Weekday::Wednesday)
 | 
			
		||||
                        }
 | 
			
		||||
                    }),
 | 
			
		||||
                    states: GermanState::list(&[
 | 
			
		||||
                        (ANY, &[Activity::range(1990, 1994)]),
 | 
			
		||||
                        (SN, &[Activity::after(1990)]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // Christmas Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Erster Weihnachtstag".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(December, 25),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Second Day Of Christmas
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Zweiter Weihnachtstag".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(December, 26),
 | 
			
		||||
                    states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
        )
 | 
			
		||||
        Self(vec![
 | 
			
		||||
            // New Years Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Neujahrstag".to_string(),
 | 
			
		||||
                date: HDate::Fixed(January, 1),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Epiphany
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Heilige drei Könige".to_string(),
 | 
			
		||||
                date: HDate::Fixed(January, 6),
 | 
			
		||||
                states: GermanState::list(&[
 | 
			
		||||
                    (BW, &[Activity::after(1990)]),
 | 
			
		||||
                    (BY, &[Activity::after(1990)]),
 | 
			
		||||
                    (ST, &[Activity::after(1990)]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // International Women's Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Internationaler Frauentag".to_string(),
 | 
			
		||||
                date: HDate::Fixed(March, 8),
 | 
			
		||||
                states: GermanState::list(&[
 | 
			
		||||
                    (BE, &[Activity::after(2019)]),
 | 
			
		||||
                    (MV, &[Activity::after(2023)]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // Good Friday
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Karfreitag".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::easter_monday(year) - Duration::days(3)),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Easter Monday
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Ostermontag".to_string(),
 | 
			
		||||
                date: HDate::Calculated(utils::easter_monday),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Labour Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Tag der Arbeit".to_string(),
 | 
			
		||||
                date: HDate::Fixed(May, 1),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Ascension Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Christi Himmelfahrt".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(38)),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Whit Monday
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Pfingstmontag".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(49)),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Corpus Christi
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Fronleichnam".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(59)),
 | 
			
		||||
                states: GermanState::list(&[
 | 
			
		||||
                    (BW, &[Activity::after(1990)]),
 | 
			
		||||
                    (BY, &[Activity::after(1990)]),
 | 
			
		||||
                    (HE, &[Activity::after(1990)]),
 | 
			
		||||
                    (NW, &[Activity::after(1990)]),
 | 
			
		||||
                    (RP, &[Activity::after(1990)]),
 | 
			
		||||
                    (SL, &[Activity::after(1990)]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // Assumption Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Mariä Himmelfahrt".to_string(),
 | 
			
		||||
                date: HDate::Fixed(August, 15),
 | 
			
		||||
                states: GermanState::list(&[
 | 
			
		||||
                    (BY, &[Activity::after(1990)]),
 | 
			
		||||
                    (SL, &[Activity::after(1990)]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // World Children's Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Weltkindertag".to_string(),
 | 
			
		||||
                date: HDate::Fixed(September, 20),
 | 
			
		||||
                states: GermanState::list(&[(TH, &[Activity::after(2019)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // German Unity Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Tag der Deutschen Einheit".to_string(),
 | 
			
		||||
                date: HDate::Fixed(October, 3),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Reformation Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Reformationstag".to_string(),
 | 
			
		||||
                date: HDate::Fixed(October, 31),
 | 
			
		||||
                states: GermanState::list(&[
 | 
			
		||||
                    (ANY, &[Activity::range(2017, 2017)]),
 | 
			
		||||
                    (BB, &[Activity::after(1990)]),
 | 
			
		||||
                    (MV, &[Activity::after(1990)]),
 | 
			
		||||
                    (SN, &[Activity::after(1990)]),
 | 
			
		||||
                    (ST, &[Activity::after(1990)]),
 | 
			
		||||
                    (TH, &[Activity::after(1990)]),
 | 
			
		||||
                    (HB, &[Activity::after(2018)]),
 | 
			
		||||
                    (HH, &[Activity::after(2018)]),
 | 
			
		||||
                    (NI, &[Activity::after(2018)]),
 | 
			
		||||
                    (SH, &[Activity::after(2018)]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // All Saints Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Allerheiligen".to_string(),
 | 
			
		||||
                date: HDate::Fixed(November, 1),
 | 
			
		||||
                states: GermanState::list(&[
 | 
			
		||||
                    (BW, &[Activity::after(1990)]),
 | 
			
		||||
                    (BY, &[Activity::after(1990)]),
 | 
			
		||||
                    (NW, &[Activity::after(1990)]),
 | 
			
		||||
                    (RP, &[Activity::after(1990)]),
 | 
			
		||||
                    (SL, &[Activity::after(1990)]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // Repentance And Prayer Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Buß- und Bettag".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| {
 | 
			
		||||
                    //	Der Buß- und Bettag ist immer ein Mittwoch, er liegt zwischen dem 16. und 22. November
 | 
			
		||||
                    let november_22 = Date::from_calendar_date(year, Month::November, 22)
 | 
			
		||||
                        .expect("22 Nov should exist every year");
 | 
			
		||||
 | 
			
		||||
                    if november_22.weekday() == Weekday::Wednesday {
 | 
			
		||||
                        november_22
 | 
			
		||||
                    } else {
 | 
			
		||||
                        november_22.prev_occurrence(Weekday::Wednesday)
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
                states: GermanState::list(&[
 | 
			
		||||
                    (ANY, &[Activity::range(1990, 1994)]),
 | 
			
		||||
                    (SN, &[Activity::after(1990)]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // Christmas Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Erster Weihnachtstag".to_string(),
 | 
			
		||||
                date: HDate::Fixed(December, 25),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Second Day Of Christmas
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Zweiter Weihnachtstag".to_string(),
 | 
			
		||||
                date: HDate::Fixed(December, 26),
 | 
			
		||||
                states: GermanState::list(&[(ANY, &[Activity::after(1990)])]),
 | 
			
		||||
            },
 | 
			
		||||
        ])
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -219,12 +217,12 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
    use crate::{
 | 
			
		||||
        HolidayChecker,
 | 
			
		||||
        countries::{CountryCode, de::GermanState},
 | 
			
		||||
        countries::{CountryState, de::GermanState},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_number_of_holidays() {
 | 
			
		||||
        let checker = HolidayChecker::new(vec![CountryCode::DE]);
 | 
			
		||||
        let checker = HolidayChecker::new();
 | 
			
		||||
 | 
			
		||||
        let tests = [
 | 
			
		||||
            (GermanState::BW, 12),
 | 
			
		||||
@ -246,7 +244,7 @@ mod tests {
 | 
			
		||||
        ];
 | 
			
		||||
        for (state, num) in tests {
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                checker.number_of_holidays(CountryCode::DE, &state.to_string(), 2025),
 | 
			
		||||
                checker.number_of_holidays(CountryState::DE(state), 2025),
 | 
			
		||||
                num
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
@ -254,27 +252,25 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_holidays() {
 | 
			
		||||
        let checker = HolidayChecker::new(vec![CountryCode::DE]);
 | 
			
		||||
        let country = CountryCode::DE;
 | 
			
		||||
        let state = GermanState::ANY.to_string();
 | 
			
		||||
        let checker = HolidayChecker::new();
 | 
			
		||||
        let country = CountryState::DE(GermanState::ANY);
 | 
			
		||||
 | 
			
		||||
        // New Years Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 01 - 01))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 01 - 01))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Epiphany
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 01 - 06))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 01 - 06))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::BW.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::BW),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 01 - 06)
 | 
			
		||||
                )
 | 
			
		||||
@ -283,14 +279,13 @@ mod tests {
 | 
			
		||||
        // International Women's Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 03 - 08))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 03 - 08))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::BE.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::BE),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 03 - 08)
 | 
			
		||||
                )
 | 
			
		||||
@ -299,44 +294,43 @@ mod tests {
 | 
			
		||||
        // Good Friday
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 04 - 18))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 04 - 18))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Easter Monday
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 04 - 21))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 04 - 21))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Labour Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 05 - 01))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 05 - 01))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Ascension Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 05 - 29))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 05 - 29))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Whit Monday
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 06 - 09))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 06 - 09))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Corpus Christi
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 06 - 19))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 06 - 19))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::BW.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::BW),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 06 - 19)
 | 
			
		||||
                )
 | 
			
		||||
@ -345,14 +339,13 @@ mod tests {
 | 
			
		||||
        // Assumption Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 08 - 15))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 08 - 15))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::BY.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::BY),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 08 - 15)
 | 
			
		||||
                )
 | 
			
		||||
@ -361,14 +354,13 @@ mod tests {
 | 
			
		||||
        // World Children's Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 09 - 20))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 09 - 20))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::TH.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::TH),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 09 - 20)
 | 
			
		||||
                )
 | 
			
		||||
@ -377,20 +369,19 @@ mod tests {
 | 
			
		||||
        // German Unity Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 10 - 03))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 10 - 03))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Reformation Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 10 - 31))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 10 - 31))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::HH.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::HH),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 10 - 31)
 | 
			
		||||
                )
 | 
			
		||||
@ -399,14 +390,13 @@ mod tests {
 | 
			
		||||
        // All Saints Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 11 - 01))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 11 - 01))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::BW.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::BW),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 11 - 01)
 | 
			
		||||
                )
 | 
			
		||||
@ -415,14 +405,13 @@ mod tests {
 | 
			
		||||
        // Repentance And Prayer Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 11 - 19))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 11 - 19))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &GermanState::SN.to_string(),
 | 
			
		||||
                    CountryState::DE(GermanState::SN),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 11 - 19)
 | 
			
		||||
                )
 | 
			
		||||
@ -431,13 +420,13 @@ mod tests {
 | 
			
		||||
        // Christmas Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 12 - 25))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 12 - 25))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Second Day Of Christmas
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 12 - 26))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 12 - 26))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
use time::Duration;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    countries::{CountryHolidays, StateList},
 | 
			
		||||
    countries::StateList,
 | 
			
		||||
    holiday::{Activity, HDate, Holiday},
 | 
			
		||||
    utils,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(super) struct FrenchHolidays;
 | 
			
		||||
pub(crate) struct FrenchHolidays(pub Vec<Holiday<FrenchState>>);
 | 
			
		||||
 | 
			
		||||
#[derive(strum::Display, Hash, PartialEq, Eq)]
 | 
			
		||||
#[derive(Debug, Clone, Copy, strum::Display, Hash, PartialEq, Eq)]
 | 
			
		||||
pub enum FrenchState {
 | 
			
		||||
    /// Bas-Rhin
 | 
			
		||||
    BasRhin,
 | 
			
		||||
@ -26,101 +26,99 @@ impl super::StateList for FrenchState {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl CountryHolidays<FrenchState> for FrenchHolidays {
 | 
			
		||||
    fn new() -> (String, Vec<Holiday>) {
 | 
			
		||||
impl FrenchHolidays {
 | 
			
		||||
    pub(crate) fn new() -> Self {
 | 
			
		||||
        use FrenchState::*;
 | 
			
		||||
        use time::Month::*;
 | 
			
		||||
        (
 | 
			
		||||
            FrenchState::all_states_identifier(),
 | 
			
		||||
            vec![
 | 
			
		||||
                // New Years Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Jour de l'an".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(January, 1),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Good Friday
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Vendredi saint".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::easter_monday(year) - Duration::days(3)),
 | 
			
		||||
                    states: FrenchState::list(&[
 | 
			
		||||
                        (BasRhin, &[Activity::unlimited()]),
 | 
			
		||||
                        (HautRhin, &[Activity::unlimited()]),
 | 
			
		||||
                        (Moselle, &[Activity::unlimited()]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
                // Easter Monday
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Lundi de Pâques".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(utils::easter_monday),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Labour Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Fête du travail".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(May, 1),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Victory Day (Second World War)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Victoire 1945".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(May, 8),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Ascension Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Ascension".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(38)),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Whit Monday
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Lundi de Pentecôte".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(49)),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // National Day (14th July)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Fête nationale".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(July, 14),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Assumption Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Assomption".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(August, 15),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // All Saints Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Toussaint".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(November, 1),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Victory Day (First World War)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Armistice 1918".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(November, 11),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Christmas Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Jour de Noël".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(December, 25),
 | 
			
		||||
                    states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Second Day Of Christmas
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Saint Étienne".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(December, 26),
 | 
			
		||||
                    states: FrenchState::list(&[
 | 
			
		||||
                        (BasRhin, &[Activity::unlimited()]),
 | 
			
		||||
                        (HautRhin, &[Activity::unlimited()]),
 | 
			
		||||
                        (Moselle, &[Activity::unlimited()]),
 | 
			
		||||
                    ]),
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        Self(vec![
 | 
			
		||||
            // New Years Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Jour de l'an".to_string(),
 | 
			
		||||
                date: HDate::Fixed(January, 1),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Good Friday
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Vendredi saint".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::easter_monday(year) - Duration::days(3)),
 | 
			
		||||
                states: FrenchState::list(&[
 | 
			
		||||
                    (BasRhin, &[Activity::unlimited()]),
 | 
			
		||||
                    (HautRhin, &[Activity::unlimited()]),
 | 
			
		||||
                    (Moselle, &[Activity::unlimited()]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
            // Easter Monday
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Lundi de Pâques".to_string(),
 | 
			
		||||
                date: HDate::Calculated(utils::easter_monday),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Labour Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Fête du travail".to_string(),
 | 
			
		||||
                date: HDate::Fixed(May, 1),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Victory Day (Second World War)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Victoire 1945".to_string(),
 | 
			
		||||
                date: HDate::Fixed(May, 8),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Ascension Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Ascension".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(38)),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Whit Monday
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Lundi de Pentecôte".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::easter_monday(year) + Duration::days(49)),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // National Day (14th July)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Fête nationale".to_string(),
 | 
			
		||||
                date: HDate::Fixed(July, 14),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Assumption Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Assomption".to_string(),
 | 
			
		||||
                date: HDate::Fixed(August, 15),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // All Saints Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Toussaint".to_string(),
 | 
			
		||||
                date: HDate::Fixed(November, 1),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Victory Day (First World War)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Armistice 1918".to_string(),
 | 
			
		||||
                date: HDate::Fixed(November, 11),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Christmas Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Jour de Noël".to_string(),
 | 
			
		||||
                date: HDate::Fixed(December, 25),
 | 
			
		||||
                states: FrenchState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Second Day Of Christmas
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Saint Étienne".to_string(),
 | 
			
		||||
                date: HDate::Fixed(December, 26),
 | 
			
		||||
                states: FrenchState::list(&[
 | 
			
		||||
                    (BasRhin, &[Activity::unlimited()]),
 | 
			
		||||
                    (HautRhin, &[Activity::unlimited()]),
 | 
			
		||||
                    (Moselle, &[Activity::unlimited()]),
 | 
			
		||||
                ]),
 | 
			
		||||
            },
 | 
			
		||||
        ])
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -130,12 +128,12 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
    use crate::{
 | 
			
		||||
        HolidayChecker,
 | 
			
		||||
        countries::{CountryCode, fr::FrenchState},
 | 
			
		||||
        countries::{CountryState, fr::FrenchState},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_number_of_holidays() {
 | 
			
		||||
        let checker = HolidayChecker::new(vec![CountryCode::FR]);
 | 
			
		||||
        let checker = HolidayChecker::new();
 | 
			
		||||
 | 
			
		||||
        let tests = [
 | 
			
		||||
            (FrenchState::BasRhin, 14),
 | 
			
		||||
@ -145,7 +143,7 @@ mod tests {
 | 
			
		||||
        ];
 | 
			
		||||
        for (state, num) in tests {
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                checker.number_of_holidays(CountryCode::FR, &state.to_string(), 2025),
 | 
			
		||||
                checker.number_of_holidays(CountryState::FR(state), 2025),
 | 
			
		||||
                num
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
@ -153,27 +151,25 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_holidays() {
 | 
			
		||||
        let checker = HolidayChecker::new(vec![CountryCode::FR]);
 | 
			
		||||
        let country = CountryCode::FR;
 | 
			
		||||
        let state = FrenchState::ANY.to_string();
 | 
			
		||||
        let checker = HolidayChecker::new();
 | 
			
		||||
        let country = CountryState::FR(FrenchState::ANY);
 | 
			
		||||
 | 
			
		||||
        // New Years Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 01 - 01))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 01 - 01))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Good Friday
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 04 - 18))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 04 - 18))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &FrenchState::BasRhin.to_string(),
 | 
			
		||||
                    CountryState::FR(FrenchState::BasRhin),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 04 - 18)
 | 
			
		||||
                )
 | 
			
		||||
@ -182,74 +178,73 @@ mod tests {
 | 
			
		||||
        // Easter Monday
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 04 - 21))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 04 - 21))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Labour Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 05 - 01))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 05 - 01))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Victory Day (Second World War)
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 05 - 08))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 05 - 08))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Ascension Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 05 - 29))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 05 - 29))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Whit Monday
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 06 - 09))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 06 - 09))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // National Day (14th July)
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 07 - 14))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 07 - 14))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Assumption Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 08 - 15))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 08 - 15))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // All Saints Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 11 - 01))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 11 - 01))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Victory Day (First World War)
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 11 - 11))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 11 - 11))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Christmas Day
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 12 - 25))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 12 - 25))
 | 
			
		||||
                .is_some()
 | 
			
		||||
        );
 | 
			
		||||
        // Second Day Of Christmas
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(country, &state, 2025, date!(2025 - 12 - 26))
 | 
			
		||||
                .is_holiday(country, 2025, date!(2025 - 12 - 26))
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            checker
 | 
			
		||||
                .is_holiday(
 | 
			
		||||
                    country,
 | 
			
		||||
                    &FrenchState::BasRhin.to_string(),
 | 
			
		||||
                    CountryState::FR(FrenchState::BasRhin),
 | 
			
		||||
                    2025,
 | 
			
		||||
                    date!(2025 - 12 - 26)
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
@ -1,22 +1,18 @@
 | 
			
		||||
mod de;
 | 
			
		||||
mod fr;
 | 
			
		||||
mod us;
 | 
			
		||||
pub mod de;
 | 
			
		||||
pub mod fr;
 | 
			
		||||
pub mod us;
 | 
			
		||||
 | 
			
		||||
use std::{collections::HashMap, fmt::Display, hash::Hash};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    countries::{de::GermanHolidays, fr::FrenchHolidays, us::USHolidays},
 | 
			
		||||
    countries::{
 | 
			
		||||
        de::{GermanHolidays, GermanState},
 | 
			
		||||
        fr::{FrenchHolidays, FrenchState},
 | 
			
		||||
        us::{USHolidays, USState},
 | 
			
		||||
    },
 | 
			
		||||
    holiday::{Activity, Holiday},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
trait CountryHolidays<T>
 | 
			
		||||
where
 | 
			
		||||
    T: StateList,
 | 
			
		||||
{
 | 
			
		||||
    /// Returns a Tuple consisting of the identifier for all states and the holiday days
 | 
			
		||||
    fn new() -> (String, Vec<Holiday>);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Represents country codes for holiday calculations
 | 
			
		||||
///
 | 
			
		||||
/// # Variants
 | 
			
		||||
@ -27,35 +23,25 @@ where
 | 
			
		||||
/// # Purpose
 | 
			
		||||
/// Provides a type-safe way to specify countries for holiday-related operations
 | 
			
		||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
 | 
			
		||||
pub enum CountryCode {
 | 
			
		||||
pub enum CountryState {
 | 
			
		||||
    /// Germany
 | 
			
		||||
    DE,
 | 
			
		||||
    DE(GermanState),
 | 
			
		||||
 | 
			
		||||
    /// The United States
 | 
			
		||||
    US,
 | 
			
		||||
    US(USState),
 | 
			
		||||
 | 
			
		||||
    /// France
 | 
			
		||||
    FR,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl CountryCode {
 | 
			
		||||
    pub(crate) fn get_holidays(&self) -> (String, Vec<Holiday>) {
 | 
			
		||||
        match self {
 | 
			
		||||
            CountryCode::DE => GermanHolidays::new(),
 | 
			
		||||
            CountryCode::US => USHolidays::new(),
 | 
			
		||||
            CountryCode::FR => FrenchHolidays::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    FR(FrenchState),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) trait StateList
 | 
			
		||||
where
 | 
			
		||||
    Self: Sized + Display + Hash + Eq,
 | 
			
		||||
    Self: Sized + Display + Hash + Eq + Clone + Copy,
 | 
			
		||||
{
 | 
			
		||||
    fn list(states: &[(Self, &[Activity])]) -> HashMap<String, Vec<Activity>> {
 | 
			
		||||
    fn list(states: &[(Self, &[Activity])]) -> HashMap<Self, Vec<Activity>> {
 | 
			
		||||
        let mut map = HashMap::new();
 | 
			
		||||
        for state in states {
 | 
			
		||||
            map.insert(state.0.to_string(), state.1.to_vec());
 | 
			
		||||
            map.insert(state.0, state.1.to_vec());
 | 
			
		||||
        }
 | 
			
		||||
        map
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
use time::{Date, Month, Weekday};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    countries::{CountryHolidays, StateList},
 | 
			
		||||
    countries::StateList,
 | 
			
		||||
    holiday::{Activity, HDate, Holiday},
 | 
			
		||||
    utils,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(super) struct USHolidays;
 | 
			
		||||
pub(crate) struct USHolidays(pub Vec<Holiday<USState>>);
 | 
			
		||||
 | 
			
		||||
#[derive(strum::Display, Hash, PartialEq, Eq)]
 | 
			
		||||
#[derive(Debug, Clone, Copy, strum::Display, Hash, PartialEq, Eq)]
 | 
			
		||||
pub enum USState {
 | 
			
		||||
    // Northeast
 | 
			
		||||
    Maine,
 | 
			
		||||
@ -82,93 +82,91 @@ impl super::StateList for USState {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl CountryHolidays<USState> for USHolidays {
 | 
			
		||||
    fn new() -> (String, Vec<Holiday>) {
 | 
			
		||||
impl USHolidays {
 | 
			
		||||
    pub(crate) fn new() -> Self {
 | 
			
		||||
        use USState::*;
 | 
			
		||||
        use time::Month::*;
 | 
			
		||||
        (
 | 
			
		||||
            USState::all_states_identifier(),
 | 
			
		||||
            vec![
 | 
			
		||||
                // NATIONAL HOLIDAYS
 | 
			
		||||
 | 
			
		||||
                // New Years Day
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "New Year's Day".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(January, 1),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Birthday of Martin Luther King, Jr. (Third Monday in January)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Martin Luther King, Jr. Day".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| {
 | 
			
		||||
                        utils::nth_weekday_in_month(year, Month::January, Weekday::Monday, 3)
 | 
			
		||||
                    }),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Inauguration Day (January 20, every 4 years following a presidential election)
 | 
			
		||||
                // Washington's Birthday (Also known as Presidents Day; third Monday in February)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Washington's Birthday".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| {
 | 
			
		||||
                        utils::nth_weekday_in_month(year, Month::February, Weekday::Monday, 3)
 | 
			
		||||
                    }),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Memorial Day (Last Monday in May)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Memorial Day".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| utils::last_monday_in_month(year, Month::May)),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Juneteenth National Independence Day (June 19)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Juneteenth".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(Month::June, 19),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Independence Day (July 4)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Independence Day".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(Month::July, 4),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Labor Day (First Monday in September)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Labor Day".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| {
 | 
			
		||||
                        utils::nth_weekday_in_month(year, Month::September, Weekday::Monday, 1)
 | 
			
		||||
                    }),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Columbus Day (Second Monday in October)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Columbus Day".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| {
 | 
			
		||||
                        utils::nth_weekday_in_month(year, Month::October, Weekday::Monday, 2)
 | 
			
		||||
                    }),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Veterans Day (November 11)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Veterans Day".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(Month::November, 11),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Thanksgiving Day (Fourth Thursday in November)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Thanksgiving Day".to_string(),
 | 
			
		||||
                    date: HDate::Calculated(|year| {
 | 
			
		||||
                        utils::nth_weekday_in_month(year, Month::November, Weekday::Thursday, 4)
 | 
			
		||||
                    }),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
                // Christmas Day (December 25)
 | 
			
		||||
                Holiday {
 | 
			
		||||
                    name: "Christmas Day".to_string(),
 | 
			
		||||
                    date: HDate::Fixed(Month::December, 25),
 | 
			
		||||
                    states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
        )
 | 
			
		||||
        Self(vec![
 | 
			
		||||
            // NATIONAL HOLIDAYS
 | 
			
		||||
 | 
			
		||||
            // New Years Day
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "New Year's Day".to_string(),
 | 
			
		||||
                date: HDate::Fixed(January, 1),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Birthday of Martin Luther King, Jr. (Third Monday in January)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Martin Luther King, Jr. Day".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| {
 | 
			
		||||
                    utils::nth_weekday_in_month(year, Month::January, Weekday::Monday, 3)
 | 
			
		||||
                }),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Inauguration Day (January 20, every 4 years following a presidential election)
 | 
			
		||||
            // Washington's Birthday (Also known as Presidents Day; third Monday in February)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Washington's Birthday".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| {
 | 
			
		||||
                    utils::nth_weekday_in_month(year, Month::February, Weekday::Monday, 3)
 | 
			
		||||
                }),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Memorial Day (Last Monday in May)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Memorial Day".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| utils::last_monday_in_month(year, Month::May)),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Juneteenth National Independence Day (June 19)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Juneteenth".to_string(),
 | 
			
		||||
                date: HDate::Fixed(Month::June, 19),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Independence Day (July 4)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Independence Day".to_string(),
 | 
			
		||||
                date: HDate::Fixed(Month::July, 4),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Labor Day (First Monday in September)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Labor Day".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| {
 | 
			
		||||
                    utils::nth_weekday_in_month(year, Month::September, Weekday::Monday, 1)
 | 
			
		||||
                }),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Columbus Day (Second Monday in October)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Columbus Day".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| {
 | 
			
		||||
                    utils::nth_weekday_in_month(year, Month::October, Weekday::Monday, 2)
 | 
			
		||||
                }),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Veterans Day (November 11)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Veterans Day".to_string(),
 | 
			
		||||
                date: HDate::Fixed(Month::November, 11),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Thanksgiving Day (Fourth Thursday in November)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Thanksgiving Day".to_string(),
 | 
			
		||||
                date: HDate::Calculated(|year| {
 | 
			
		||||
                    utils::nth_weekday_in_month(year, Month::November, Weekday::Thursday, 4)
 | 
			
		||||
                }),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
            // Christmas Day (December 25)
 | 
			
		||||
            Holiday {
 | 
			
		||||
                name: "Christmas Day".to_string(),
 | 
			
		||||
                date: HDate::Fixed(Month::December, 25),
 | 
			
		||||
                states: USState::list(&[(ANY, &[Activity::unlimited()])]),
 | 
			
		||||
            },
 | 
			
		||||
        ])
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,9 @@
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::{collections::HashMap, hash::Hash};
 | 
			
		||||
 | 
			
		||||
use time::{Date, Month};
 | 
			
		||||
 | 
			
		||||
use crate::HolidayDate;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub(crate) struct Activity {
 | 
			
		||||
    unlimited: bool,
 | 
			
		||||
@ -49,22 +51,49 @@ pub(crate) enum HDate {
 | 
			
		||||
    Calculated(fn(i32) -> Date),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub(crate) struct Holiday {
 | 
			
		||||
    pub(crate) name: String,
 | 
			
		||||
    pub(crate) date: HDate,
 | 
			
		||||
    pub(crate) states: HashMap<String, Vec<Activity>>,
 | 
			
		||||
impl HDate {
 | 
			
		||||
    pub(crate) fn to_date(&self, year: i32, name: &str) -> HolidayDate {
 | 
			
		||||
        match self {
 | 
			
		||||
            HDate::Calculated(calc_fn) => {
 | 
			
		||||
                // For holidays with calculation function
 | 
			
		||||
                HolidayDate {
 | 
			
		||||
                    date: calc_fn(year),
 | 
			
		||||
                    name: name.to_string(),
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            HDate::Fixed(month, day) => {
 | 
			
		||||
                // For fixed date holidays
 | 
			
		||||
                HolidayDate {
 | 
			
		||||
                    date: Date::from_calendar_date(year, *month, *day).unwrap(),
 | 
			
		||||
                    name: name.to_string(),
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Holiday {
 | 
			
		||||
    pub(crate) fn is_active(&self, year: i32, all_states_identifier: &str, state: &str) -> bool {
 | 
			
		||||
        if let Some(all_states) = self.states.get(all_states_identifier) {
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub(crate) struct Holiday<T>
 | 
			
		||||
where
 | 
			
		||||
    T: Hash + Eq,
 | 
			
		||||
{
 | 
			
		||||
    pub(crate) name: String,
 | 
			
		||||
    pub(crate) date: HDate,
 | 
			
		||||
    pub(crate) states: HashMap<T, Vec<Activity>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> Holiday<T>
 | 
			
		||||
where
 | 
			
		||||
    T: Hash + Eq,
 | 
			
		||||
{
 | 
			
		||||
    pub(crate) fn is_active(&self, year: i32, all_states_identifier: T, state: T) -> bool {
 | 
			
		||||
        if let Some(all_states) = self.states.get(&all_states_identifier) {
 | 
			
		||||
            // if holiday is valid for all states and is active in that year
 | 
			
		||||
            if all_states.iter().any(|activity| activity.is_active(year)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if let Some(all_states) = self.states.get(state) {
 | 
			
		||||
        if let Some(all_states) = self.states.get(&state) {
 | 
			
		||||
            // if holiday is only valid for this states and is active in that year
 | 
			
		||||
            if all_states.iter().any(|activity| activity.is_active(year)) {
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										165
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								src/lib.rs
									
									
									
									
									
								
							@ -1,18 +1,21 @@
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
 | 
			
		||||
pub use time::Date;
 | 
			
		||||
 | 
			
		||||
use crate::countries::de::{GermanHolidays, GermanState};
 | 
			
		||||
use crate::countries::fr::{FrenchHolidays, FrenchState};
 | 
			
		||||
use crate::countries::us::{USHolidays, USState};
 | 
			
		||||
use crate::holiday::{HDate, Holiday};
 | 
			
		||||
 | 
			
		||||
mod countries;
 | 
			
		||||
mod holiday;
 | 
			
		||||
pub(crate) mod utils;
 | 
			
		||||
 | 
			
		||||
pub use countries::CountryCode;
 | 
			
		||||
use countries::CountryState;
 | 
			
		||||
 | 
			
		||||
/// A struct to manage and check holidays for different countries
 | 
			
		||||
pub struct HolidayChecker {
 | 
			
		||||
    countries: HashMap<CountryCode, (String, Vec<Holiday>)>,
 | 
			
		||||
    de: GermanHolidays,
 | 
			
		||||
    us: USHolidays,
 | 
			
		||||
    fr: FrenchHolidays,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl HolidayChecker {
 | 
			
		||||
@ -23,15 +26,12 @@ impl HolidayChecker {
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Returns
 | 
			
		||||
    /// A new HolidayChecker instance with holidays for the specified countries
 | 
			
		||||
    pub fn new(countries: Vec<CountryCode>) -> Self {
 | 
			
		||||
        let mut map = HashMap::new();
 | 
			
		||||
 | 
			
		||||
        for country in countries {
 | 
			
		||||
            let holidays = country.get_holidays();
 | 
			
		||||
            map.insert(country, holidays);
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            de: GermanHolidays::new(),
 | 
			
		||||
            fr: FrenchHolidays::new(),
 | 
			
		||||
            us: USHolidays::new(),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Self { countries: map }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Retrieves a list of holidays for a specific country, state, and year
 | 
			
		||||
@ -43,14 +43,8 @@ impl HolidayChecker {
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Returns
 | 
			
		||||
    /// A vector of HolidayDate for the specified country, state, and year
 | 
			
		||||
    pub fn holiday_list(&self, country: CountryCode, state: &str, year: i32) -> Vec<HolidayDate> {
 | 
			
		||||
        Self::get_years_holidays(
 | 
			
		||||
            self.countries
 | 
			
		||||
                .get(&country)
 | 
			
		||||
                .unwrap_or(&(String::new(), vec![])),
 | 
			
		||||
            year,
 | 
			
		||||
            state,
 | 
			
		||||
        )
 | 
			
		||||
    pub fn holiday_list(&self, country: CountryState, year: i32) -> Vec<HolidayDate> {
 | 
			
		||||
        self.get_years_holidays(country, year)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Counts the number of holidays for a specific country, state, and year
 | 
			
		||||
@ -62,15 +56,8 @@ impl HolidayChecker {
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Returns
 | 
			
		||||
    /// The number of holidays for the specified country, state, and year
 | 
			
		||||
    pub fn number_of_holidays(&self, country: CountryCode, state: &str, year: i32) -> usize {
 | 
			
		||||
        Self::get_years_holidays(
 | 
			
		||||
            self.countries
 | 
			
		||||
                .get(&country)
 | 
			
		||||
                .unwrap_or(&(String::new(), vec![])),
 | 
			
		||||
            year,
 | 
			
		||||
            state,
 | 
			
		||||
        )
 | 
			
		||||
        .len()
 | 
			
		||||
    pub fn number_of_holidays(&self, country: CountryState, year: i32) -> usize {
 | 
			
		||||
        self.get_years_holidays(country, year).len()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Checks if a specific date is a holiday for a given country, state, and year
 | 
			
		||||
@ -83,26 +70,14 @@ impl HolidayChecker {
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Returns
 | 
			
		||||
    /// An Option containing the HolidayDate if the date is a holiday, None otherwise
 | 
			
		||||
    pub fn is_holiday(
 | 
			
		||||
        &self,
 | 
			
		||||
        country: CountryCode,
 | 
			
		||||
        state: &str,
 | 
			
		||||
        year: i32,
 | 
			
		||||
        date: Date,
 | 
			
		||||
    ) -> Option<HolidayDate> {
 | 
			
		||||
        Self::get_years_holidays(
 | 
			
		||||
            self.countries
 | 
			
		||||
                .get(&country)
 | 
			
		||||
                .unwrap_or(&(String::new(), vec![])),
 | 
			
		||||
            year,
 | 
			
		||||
            state,
 | 
			
		||||
        )
 | 
			
		||||
        .iter()
 | 
			
		||||
        .find(|holiday| holiday.date == date)
 | 
			
		||||
        .map(|holiday| HolidayDate {
 | 
			
		||||
            name: holiday.name.clone(),
 | 
			
		||||
            date,
 | 
			
		||||
        })
 | 
			
		||||
    pub fn is_holiday(&self, country: CountryState, year: i32, date: Date) -> Option<HolidayDate> {
 | 
			
		||||
        self.get_years_holidays(country, year)
 | 
			
		||||
            .iter()
 | 
			
		||||
            .find(|holiday| holiday.date == date)
 | 
			
		||||
            .map(|holiday| HolidayDate {
 | 
			
		||||
                name: holiday.name.clone(),
 | 
			
		||||
                date,
 | 
			
		||||
            })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Internal method to retrieve holidays for a specific year and state
 | 
			
		||||
@ -114,37 +89,71 @@ impl HolidayChecker {
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Returns
 | 
			
		||||
    /// A vector of HolidayDate for the specified year and state
 | 
			
		||||
    fn get_years_holidays(
 | 
			
		||||
        holidays: &(String, Vec<Holiday>),
 | 
			
		||||
        year: i32,
 | 
			
		||||
        state: &str,
 | 
			
		||||
    ) -> Vec<HolidayDate> {
 | 
			
		||||
        let (all_states_identifier, holidays) = holidays;
 | 
			
		||||
        holidays
 | 
			
		||||
            .iter()
 | 
			
		||||
            .filter_map(|holiday| {
 | 
			
		||||
                // check if holiday is active
 | 
			
		||||
                if !holiday.is_active(year, all_states_identifier, state) {
 | 
			
		||||
                    return None;
 | 
			
		||||
                }
 | 
			
		||||
                match holiday.date {
 | 
			
		||||
                    HDate::Calculated(calc_fn) => {
 | 
			
		||||
                        // For holidays with calculation function
 | 
			
		||||
                        Some(HolidayDate {
 | 
			
		||||
                            date: calc_fn(year),
 | 
			
		||||
                            name: holiday.name.clone(),
 | 
			
		||||
                        })
 | 
			
		||||
    fn get_years_holidays(&self, country: CountryState, year: i32) -> Vec<HolidayDate> {
 | 
			
		||||
        match country {
 | 
			
		||||
            CountryState::DE(state) => self
 | 
			
		||||
                .de
 | 
			
		||||
                .0
 | 
			
		||||
                .iter()
 | 
			
		||||
                .filter_map(|holiday| {
 | 
			
		||||
                    // check if holiday is active
 | 
			
		||||
                    if !holiday.is_active(year, GermanState::ANY, state) {
 | 
			
		||||
                        return None;
 | 
			
		||||
                    }
 | 
			
		||||
                    HDate::Fixed(month, day) => {
 | 
			
		||||
                        // For fixed date holidays
 | 
			
		||||
                        Some(HolidayDate {
 | 
			
		||||
                            date: Date::from_calendar_date(year, month, day).unwrap(),
 | 
			
		||||
                            name: holiday.name.clone(),
 | 
			
		||||
                        })
 | 
			
		||||
                    Some(holiday.date.to_date(year, &holiday.name))
 | 
			
		||||
                })
 | 
			
		||||
                .collect(),
 | 
			
		||||
            CountryState::US(state) => self
 | 
			
		||||
                .us
 | 
			
		||||
                .0
 | 
			
		||||
                .iter()
 | 
			
		||||
                .filter_map(|holiday| {
 | 
			
		||||
                    // check if holiday is active
 | 
			
		||||
                    if !holiday.is_active(year, USState::ANY, state) {
 | 
			
		||||
                        return None;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .collect()
 | 
			
		||||
                    Some(holiday.date.to_date(year, &holiday.name))
 | 
			
		||||
                })
 | 
			
		||||
                .collect(),
 | 
			
		||||
            CountryState::FR(state) => self
 | 
			
		||||
                .fr
 | 
			
		||||
                .0
 | 
			
		||||
                .iter()
 | 
			
		||||
                .filter_map(|holiday| {
 | 
			
		||||
                    // check if holiday is active
 | 
			
		||||
                    if !holiday.is_active(year, FrenchState::ANY, state) {
 | 
			
		||||
                        return None;
 | 
			
		||||
                    }
 | 
			
		||||
                    Some(holiday.date.to_date(year, &holiday.name))
 | 
			
		||||
                })
 | 
			
		||||
                .collect(),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // holidays
 | 
			
		||||
        //     .iter()
 | 
			
		||||
        //     .filter_map(|holiday| {
 | 
			
		||||
        //         // check if holiday is active
 | 
			
		||||
        //         if !holiday.is_active(year, all_states_identifier, state) {
 | 
			
		||||
        //             return None;
 | 
			
		||||
        //         }
 | 
			
		||||
        //         match holiday.date {
 | 
			
		||||
        //             HDate::Calculated(calc_fn) => {
 | 
			
		||||
        //                 // For holidays with calculation function
 | 
			
		||||
        //                 Some(HolidayDate {
 | 
			
		||||
        //                     date: calc_fn(year),
 | 
			
		||||
        //                     name: holiday.name.clone(),
 | 
			
		||||
        //                 })
 | 
			
		||||
        //             }
 | 
			
		||||
        //             HDate::Fixed(month, day) => {
 | 
			
		||||
        //                 // For fixed date holidays
 | 
			
		||||
        //                 Some(HolidayDate {
 | 
			
		||||
        //                     date: Date::from_calendar_date(year, month, day).unwrap(),
 | 
			
		||||
        //                     name: holiday.name.clone(),
 | 
			
		||||
        //                 })
 | 
			
		||||
        //             }
 | 
			
		||||
        //         }
 | 
			
		||||
        //     })
 | 
			
		||||
        //     .collect()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user