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() { match property.name.as_str() {
"UID" => uid = uid.or(Some(value)), "UID" => uid = uid.or(Some(value)),
"RRULE" => rrule = rrule.or(Some(value)), "RRULE" => rrule = rrule.or(Some(value)),
"DTSTART" => start = start.or(parse_date(property.params, &value)), "DTSTART" => {
"DTEND" => end = end.or(parse_date(property.params, &value)), start = start.or(parse_dates(property.params, &value).into_iter().next())
"RECURRENCE-ID" => {
recurrence_id = recurrence_id.or(parse_date(property.params, &value))
} }
"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() .into_iter()
.for_each(|date| exdates.push(date)), .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>> { // TODO This should return a result instead
let params = params?; fn parse_dates(params: Option<Vec<(String, Vec<String>)>>, value: &str) -> Vec<DateTime<Tz>> {
let datetime = NaiveDateTime::parse_from_str(value, "%Y%m%dT%H%M%S").ok()?; let params = if let Some(params) = params {
params
} else {
return vec![];
};
// Find TZID parameter and extract its singular value // Find TZID parameter and extract its singular value
let tz = params let tz = params
.into_iter() .into_iter()
@@ -181,8 +190,16 @@ fn parse_date(params: Option<Vec<(String, Vec<String>)>>, value: &str) -> Option
.into_iter() .into_iter()
.next() .next()
.unwrap(); .unwrap();
let tz: chrono_tz::Tz = tz.parse().ok()?; let tz: chrono_tz::Tz = if let Ok(tz) = tz.parse() {
let datetime = match tz.from_local_datetime(&datetime) { 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::Single(datetime) => Some(datetime),
LocalResult::None => None, LocalResult::None => None,
LocalResult::Ambiguous(_, _) => { LocalResult::Ambiguous(_, _) => {
@@ -193,6 +210,7 @@ fn parse_date(params: Option<Vec<(String, Vec<String>)>>, value: &str) -> Option
); );
None None
} }
}?; })
Some(datetime.with_timezone(&datetime.timezone().into())) .map(|datetime| datetime.with_timezone(&datetime.timezone().into()))
.collect::<Vec<_>>()
} }