Add support for comma separated EXDATEs

This commit is contained in:
2022-11-22 14:55:50 +01:00
parent 2ecfd205d4
commit ed9bd87ab5

View File

@@ -141,12 +141,17 @@ impl Event {
match property.name.as_str() {
"UID" => uid = uid.or(Some(value)),
"RRULE" => rrule = rrule.or(Some(value)),
"DTSTART" => start = start.or(parse_date(property.params, &value)),
"DTEND" => end = end.or(parse_date(property.params, &value)),
"RECURRENCE-ID" => {
recurrence_id = recurrence_id.or(parse_date(property.params, &value))
"DTSTART" => {
start = start.or(parse_dates(property.params, &value).into_iter().next())
}
"EXDATE" => parse_date(property.params, &value)
"DTEND" => {
end = end.or(parse_dates(property.params, &value).into_iter().next())
}
"RECURRENCE-ID" => {
recurrence_id = recurrence_id
.or(parse_dates(property.params, &value).into_iter().next())
}
"EXDATE" => parse_dates(property.params, &value)
.into_iter()
.for_each(|date| exdates.push(date)),
_ => {}
@@ -167,9 +172,13 @@ impl Event {
}
}
fn parse_date(params: Option<Vec<(String, Vec<String>)>>, value: &str) -> Option<DateTime<Tz>> {
let params = params?;
let datetime = NaiveDateTime::parse_from_str(value, "%Y%m%dT%H%M%S").ok()?;
// TODO This should return a result instead
fn parse_dates(params: Option<Vec<(String, Vec<String>)>>, value: &str) -> Vec<DateTime<Tz>> {
let params = if let Some(params) = params {
params
} else {
return vec![];
};
// Find TZID parameter and extract its singular value
let tz = params
.into_iter()
@@ -181,18 +190,27 @@ fn parse_date(params: Option<Vec<(String, Vec<String>)>>, value: &str) -> Option
.into_iter()
.next()
.unwrap();
let tz: chrono_tz::Tz = tz.parse().ok()?;
let datetime = match tz.from_local_datetime(&datetime) {
LocalResult::Single(datetime) => Some(datetime),
LocalResult::None => None,
LocalResult::Ambiguous(_, _) => {
warn!(
"Ignoring ambiguous datetime '{}' from timezone '{}'",
datetime,
tz.name()
);
None
}
}?;
Some(datetime.with_timezone(&datetime.timezone().into()))
let tz: chrono_tz::Tz = if let Ok(tz) = tz.parse() {
tz
} else {
return vec![];
};
value
.split(',')
.filter_map(|time_str| NaiveDateTime::parse_from_str(time_str, "%Y%m%dT%H%M%S").ok())
.filter_map(|datetime| match tz.from_local_datetime(&datetime) {
LocalResult::Single(datetime) => Some(datetime),
LocalResult::None => None,
LocalResult::Ambiguous(_, _) => {
warn!(
"Ignoring ambiguous datetime '{}' from timezone '{}'",
datetime,
tz.name()
);
None
}
})
.map(|datetime| datetime.with_timezone(&datetime.timezone().into()))
.collect::<Vec<_>>()
}