1use std::fmt::Debug;
2use std::sync::Arc;
3
4use compact_calendar::CompactCalendar;
5use opening_hours_syntax::rules::day::HolidayKind;
6
7use crate::localization::{Localize, NoLocation};
8
9#[derive(Clone, Default, Debug, Hash, PartialEq, Eq)]
15pub struct ContextHolidays {
16 pub(crate) public: Arc<CompactCalendar>,
17 pub(crate) school: Arc<CompactCalendar>,
18}
19
20impl ContextHolidays {
21 pub fn new(public: Arc<CompactCalendar>, school: Arc<CompactCalendar>) -> Self {
23 Self { public, school }
24 }
25
26 pub fn get_public(&self) -> &CompactCalendar {
28 &self.public
29 }
30
31 pub fn get_school(&self) -> &CompactCalendar {
33 &self.school
34 }
35
36 pub fn get_for_kind(&self, kind: HolidayKind) -> &CompactCalendar {
38 match kind {
39 HolidayKind::Public => &self.public,
40 HolidayKind::School => &self.school,
41 }
42 }
43}
44
45#[derive(Clone, Debug, Hash, PartialEq, Eq)]
48pub struct Context<L = NoLocation> {
49 pub holidays: ContextHolidays,
51 pub holidays_unknown: ContextHolidays,
55 pub locale: L,
58 pub approx_bound_interval_size: Option<chrono::TimeDelta>,
62}
63
64impl<L> Context<L> {
65 pub fn with_holidays(self, holidays: ContextHolidays) -> Self {
67 Self { holidays, ..self }
68 }
69
70 pub fn with_holidays_unknown(self, holidays_unknown: ContextHolidays) -> Self {
72 Self { holidays_unknown, ..self }
73 }
74
75 pub fn with_locale<L2: Localize>(self, locale: L2) -> Context<L2> {
77 Context {
78 locale,
79 holidays: self.holidays,
80 holidays_unknown: self.holidays_unknown,
81 approx_bound_interval_size: self.approx_bound_interval_size,
82 }
83 }
84
85 pub fn approx_bound_interval_size(self, max_size: chrono::TimeDelta) -> Self {
87 Self { approx_bound_interval_size: Some(max_size), ..self }
88 }
89}
90
91#[cfg(feature = "auto-timezone")]
92impl Context<crate::localization::TzLocation<chrono_tz::Tz>> {
93 #[cfg(feature = "auto-country")]
110 pub fn from_coords(coords: crate::localization::Coordinates) -> Self {
111 use crate::localization::Country;
112
113 let locale = crate::localization::TzLocation::from_coords(coords);
114 let country_res = Country::try_from_coords(coords);
115 let holidays = country_res.map(Country::holidays).unwrap_or_default();
116
117 let holidays_unknown = country_res
118 .map(Country::holidays_regional)
119 .unwrap_or_default();
120
121 Self {
122 holidays,
123 holidays_unknown,
124 locale,
125 approx_bound_interval_size: None,
126 }
127 }
128}
129
130impl Default for Context<NoLocation> {
131 fn default() -> Self {
132 Self {
133 holidays: Default::default(),
134 holidays_unknown: Default::default(),
135 locale: NoLocation,
136 approx_bound_interval_size: None,
137 }
138 }
139}