opening_hours/context.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
use std::fmt::Debug;
use std::sync::Arc;
use compact_calendar::CompactCalendar;
use crate::localization::{Localize, NoLocation};
// --
// -- Holidays
// --
/// Pairs a set of public holidays with a set of school holidays.
#[derive(Clone, Default, Debug, Hash, PartialEq, Eq)]
pub struct ContextHolidays {
pub(crate) public: Arc<CompactCalendar>,
pub(crate) school: Arc<CompactCalendar>,
}
impl ContextHolidays {
/// Create a new holidays context from sets of public and school holidays.
pub fn new(public: Arc<CompactCalendar>, school: Arc<CompactCalendar>) -> Self {
Self { public, school }
}
/// Get the set of public holidays attached to this context.
pub fn get_public(&self) -> &CompactCalendar {
&self.public
}
/// Get the set of school holidays attached to this context.
pub fn get_school(&self) -> &CompactCalendar {
&self.school
}
}
/// All the context attached to a parsed OpeningHours expression and that can
/// alter its evaluation semantics.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Context<L = NoLocation> {
pub holidays: ContextHolidays,
pub locale: L,
}
impl<L> Context<L> {
/// Attach a new holidays component to this context.
pub fn with_holidays(self, holidays: ContextHolidays) -> Self {
Self { holidays, ..self }
}
/// Attach a new locale component to this context.
pub fn with_locale<L2: Localize>(self, locale: L2) -> Context<L2> {
Context { holidays: self.holidays, locale }
}
}
#[cfg(feature = "auto-timezone")]
impl Context<crate::localization::TzLocation<chrono_tz::Tz>> {
/// Create a context with given coordinates and try to infer a timezone and
/// a local holiday calendar.
///
/// ```
/// use opening_hours::Context;
/// use opening_hours::localization::{Coordinates, Country, TzLocation};
///
/// let coords = Coordinates::new(48.8535, 2.34839).unwrap();
///
/// assert_eq!(
/// Context::from_coords(coords),
/// Context::default()
/// .with_holidays(Country::FR.holidays())
/// .with_locale(TzLocation::from_coords(coords)),
/// );
/// ```
#[cfg(feature = "auto-country")]
pub fn from_coords(coords: crate::localization::Coordinates) -> Self {
use crate::localization::Country;
let holidays = Country::try_from_coords(coords)
.map(Country::holidays)
.unwrap_or_default();
let locale = crate::localization::TzLocation::from_coords(coords);
Self { holidays, locale }
}
}
impl Default for Context<NoLocation> {
fn default() -> Self {
Self { holidays: Default::default(), locale: NoLocation }
}
}