use crate::ArcStr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DayKind {
Feast(ArcStr),
Sunday {
number: ArcStr,
season: ArcStr,
week_of_month: Option<u8>,
},
Feria {
day: ArcStr,
week: ArcStr,
season: ArcStr,
week_of_month: Option<u8>,
},
Unknown,
}
impl DayKind {
#[must_use]
pub fn from_desc(desc: &str) -> Self {
let s = desc.trim();
if s.is_empty() {
return DayKind::Unknown;
}
let lc = s.to_lowercase();
if lc.starts_with("dominica") || lc.starts_with("dom.") || lc.contains("sunday") {
if let Some(pos) = lc.find(" of ") {
let number = s["dominica".len()..pos].trim().to_string();
let season = s[pos + 4..].trim().to_string();
return DayKind::Sunday {
number: ArcStr::from(number),
season: ArcStr::from(season),
week_of_month: None,
};
}
if let Some(pos) = lc.find(" in ") {
let number = s["dominica".len()..pos].trim().to_string();
let season = s[pos + 4..].trim().to_string();
return DayKind::Sunday {
number: ArcStr::from(number),
season: ArcStr::from(season),
week_of_month: None,
};
}
if let Some(space) = s.find(' ') {
let rest = s[space + 1..].trim().to_string();
return DayKind::Sunday {
number: ArcStr::from(String::new()),
season: ArcStr::from(rest),
week_of_month: None,
};
}
return DayKind::Sunday {
number: ArcStr::from(String::new()),
season: ArcStr::from(String::new()),
week_of_month: None,
};
}
if lc.starts_with("feria") || lc.starts_with("weekday") || lc.starts_with("monday") {
let mut season = String::new();
if let Some(pos) = lc.find(" of ") {
let sfx = s[pos + 4..].trim();
if !sfx.is_empty() {
season = sfx.to_string();
}
}
return DayKind::Feria {
day: ArcStr::from(s.to_string()),
week: ArcStr::from(String::new()),
season: ArcStr::from(season),
week_of_month: None,
};
}
DayKind::Feast(ArcStr::from(s.to_string()))
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn parse_dominica_of_advent() {
let k = DayKind::from_desc("Dominica II of Advent");
match k {
DayKind::Sunday {
number,
season,
week_of_month,
} => {
assert!(!number.as_ref().is_empty());
assert_eq!(season.as_ref().to_lowercase(), "advent");
assert!(week_of_month.is_none());
}
_ => panic!("expected Sunday kind"),
}
}
#[test]
fn parse_dominica_palm() {
let k = DayKind::from_desc("Dominica Palm Sunday");
match k {
DayKind::Sunday { season, .. } => {
assert_eq!(season.as_ref().to_lowercase(), "palm sunday");
}
_ => panic!("expected Sunday kind"),
}
}
}