Add support for comma separated EXDATEs
This commit is contained in:
@@ -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<_>>()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user