badi_date/bahai_holy_day/
holy_day_providing.rs1use crate::{BadiDateError, BadiDateLike, BahaiHolyDay};
2
3pub trait HolyDayProviding: BadiDateLike {
5 fn holy_day(&self) -> Option<BahaiHolyDay> {
7 BahaiHolyDay::holy_days_for_year(self.year())
8 .get(&self.day_of_year())
9 .cloned()
10 }
11
12 fn next_holy_day(&self) -> Result<Self, BadiDateError> {
14 for year in [self.year(), self.year() + 1] {
15 let after_day = if year == self.year() {
16 self.day_of_year()
17 } else {
18 0
19 };
20 if let Some((day_of_year, _holy_day)) = BahaiHolyDay::holy_days_for_year(year)
21 .into_iter()
22 .find(|(day_of_year, _)| *day_of_year > after_day)
23 {
24 return self.with_year_and_doy(year, day_of_year);
25 }
26 }
27 Err(BadiDateError::DateNotSupported)
28 }
29
30 fn previous_holy_day(&self) -> Result<Self, BadiDateError> {
32 for year in [self.year(), self.year() - 1] {
33 let before_day = if year == self.year() {
34 self.day_of_year()
35 } else {
36 366
37 };
38 if let Some((day_of_year, _holy_day)) = BahaiHolyDay::holy_days_for_year(year)
39 .into_iter()
40 .filter(|(day_of_year, _)| *day_of_year < before_day)
41 .last()
42 {
43 return self.with_year_and_doy(year, day_of_year);
44 }
45 }
46 Err(BadiDateError::DateNotSupported)
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use crate::{BadiDate, BadiDateOps, BadiMonth, BahaiHolyDay, HolyDayProviding};
53
54 #[test]
55 fn add_subtract_next_previous() {
56 let badi = BadiDate::new(181, BadiMonth::Month(5), 2).unwrap();
58 let next_holy_day: BadiDate = badi.next_holy_day().unwrap();
59 assert_eq!(
60 next_holy_day,
61 BadiDate::new(181, BadiMonth::Month(6), 17).unwrap(),
63 );
64 assert_eq!(
65 next_holy_day.holy_day(),
66 Some(BahaiHolyDay::MartyrdomOfTheBab)
67 );
68 assert!(next_holy_day.holy_day().unwrap().work_suspended());
69 let next_holy_day: BadiDate = next_holy_day.next_holy_day().unwrap();
70 assert_eq!(
71 next_holy_day,
72 BadiDate::new(181, BadiMonth::Month(12), 19).unwrap(),
74 );
75 assert_eq!(next_holy_day.holy_day(), Some(BahaiHolyDay::BirthOfTheBab));
76 let next_holy_day: BadiDate = next_holy_day.next_holy_day().unwrap();
77 assert_eq!(
78 next_holy_day,
79 BadiDate::new(181, BadiMonth::Month(13), 1).unwrap(),
81 );
82 assert_eq!(
83 next_holy_day.holy_day(),
84 Some(BahaiHolyDay::BirthOfBahaullah)
85 );
86 let next_day = next_holy_day.next_day();
87 assert_eq!(next_day.holy_day(), None);
88 let next_holy_day: BadiDate = next_holy_day
89 .next_holy_day()
90 .unwrap()
91 .next_holy_day()
92 .unwrap();
93 assert_eq!(
94 next_holy_day,
95 BadiDate::new(181, BadiMonth::Month(14), 6).unwrap(),
97 );
98 let prev_holy_day = badi.previous_holy_day().unwrap();
99 assert_eq!(
100 prev_holy_day,
101 BadiDate::new(181, BadiMonth::Month(4), 13).unwrap(),
103 );
104 let prev_holy_day = prev_holy_day.previous_holy_day().unwrap();
105 assert_eq!(
106 prev_holy_day,
107 BadiDate::new(181, BadiMonth::Month(4), 8).unwrap(),
109 );
110
111 let badi = BadiDate::new(181, BadiMonth::AyyamIHa, 2).unwrap();
112 let next_holy_day: BadiDate = badi.next_holy_day().unwrap();
113 assert_eq!(
114 next_holy_day,
115 BadiDate::new(182, BadiMonth::Month(1), 1).unwrap(),
117 );
118 assert_eq!(next_holy_day.holy_day(), Some(BahaiHolyDay::NawRuz),);
119
120 let previous_holy_day: BadiDate = next_holy_day.previous_holy_day().unwrap();
121 assert_eq!(
122 previous_holy_day,
123 BadiDate::new(181, BadiMonth::Month(14), 6).unwrap(),
125 );
126 assert_eq!(
127 previous_holy_day.holy_day(),
128 Some(BahaiHolyDay::AscensionOfAbdulBaha),
129 );
130 assert!(!previous_holy_day.holy_day().unwrap().work_suspended(),);
131 }
132}