ics: implement support for multiple values per key
This commit is contained in:
parent
553ccc6ad7
commit
7453b01191
|
@ -15,21 +15,21 @@ pub type Props = Vec<(String, String)>;
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Object {
|
pub struct Object {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub content: HashMap<String, (Props, String)>,
|
pub content: HashMap<String, Vec<(Props, String)>>,
|
||||||
pub children: Vec<Box<Object>>,
|
pub children: Vec<Box<Object>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GetValue<'a, &'a str> for Object {
|
impl<'a> GetValue<'a, &'a str> for Object {
|
||||||
fn get(&'a self, key: &'_ str) -> Option<&'a str> {
|
fn get(&'a self, key: &'_ str) -> Option<&'a str> {
|
||||||
self.content.get(key)
|
self.content.get(key)
|
||||||
.map(|(_props, value)| value.as_ref())
|
.and_then(|pairs| pairs.first().map(|(_props, ref value)| value.as_str()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GetValue<'a, String> for Object {
|
impl<'a> GetValue<'a, String> for Object {
|
||||||
fn get(&self, key: &'_ str) -> Option<String> {
|
fn get(&self, key: &'_ str) -> Option<String> {
|
||||||
self.content.get(key)
|
self.content.get(key)
|
||||||
.map(|(_props, value)| value.clone())
|
.and_then(|pairs| pairs.first().map(|(_props, value)| value.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,10 @@ impl Parser {
|
||||||
let key = replace(current_key, None);
|
let key = replace(current_key, None);
|
||||||
let objects_len = objects.len();
|
let objects_len = objects.len();
|
||||||
let content = &mut objects[objects_len - 1].content;
|
let content = &mut objects[objects_len - 1].content;
|
||||||
key.map(|key| content.insert(key, (props, value)));
|
key.map(|key| content.entry(key)
|
||||||
|
.or_insert_with(|| vec![])
|
||||||
|
.push((props, value))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +90,6 @@ mod test {
|
||||||
p.feed(b"BEGIN:VEVENT
|
p.feed(b"BEGIN:VEVENT
|
||||||
SUMMARY:Test event
|
SUMMARY:Test event
|
||||||
DTSTART:19700101
|
DTSTART:19700101
|
||||||
RRULE:FREQ=YEARLY
|
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
|
|
||||||
", |o| {
|
", |o| {
|
||||||
|
@ -97,11 +99,41 @@ END:VEVENT
|
||||||
assert_eq!(obj, Some(Object {
|
assert_eq!(obj, Some(Object {
|
||||||
name: "VEVENT".to_owned(),
|
name: "VEVENT".to_owned(),
|
||||||
content: [("SUMMARY", "Test event"),
|
content: [("SUMMARY", "Test event"),
|
||||||
("RRULE", "FREQ=YEARLY"),
|
|
||||||
("DTSTART", "19700101")]
|
("DTSTART", "19700101")]
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|(k, v)| (k.to_owned(), (vec![], v.to_owned())))
|
.map(|(k, v)| (k.to_owned(), vec![(vec![], v.to_owned())]))
|
||||||
|
.collect(),
|
||||||
|
children: vec![],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_recurring_event() {
|
||||||
|
let mut p = Parser::new();
|
||||||
|
let mut obj = None;
|
||||||
|
p.feed(b"BEGIN:VEVENT
|
||||||
|
SUMMARY:Test event
|
||||||
|
DTSTART:19700101
|
||||||
|
RRULE:FREQ=YEARLY
|
||||||
|
EXDATE:19710101
|
||||||
|
EXDATE:19730101
|
||||||
|
EXDATE:19770101
|
||||||
|
END:VEVENT
|
||||||
|
|
||||||
|
", |o| {
|
||||||
|
assert!(obj.is_none());
|
||||||
|
obj = Some(o);
|
||||||
|
});
|
||||||
|
assert_eq!(obj, Some(Object {
|
||||||
|
name: "VEVENT".to_owned(),
|
||||||
|
content: [("SUMMARY", vec!["Test event"]),
|
||||||
|
("RRULE", vec!["FREQ=YEARLY"]),
|
||||||
|
("EXDATE", vec!["19710101", "19730101", "19770101"]),
|
||||||
|
("DTSTART", vec!["19700101"])]
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(|(k, v)| (k.to_owned(), v.into_iter().map(|v| (vec![], v.to_owned())).collect()))
|
||||||
.collect(),
|
.collect(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
}));
|
}));
|
||||||
|
@ -123,8 +155,8 @@ END:VEVENT
|
||||||
assert_eq!(obj, Some(Object {
|
assert_eq!(obj, Some(Object {
|
||||||
name: "VEVENT".to_owned(),
|
name: "VEVENT".to_owned(),
|
||||||
content: [
|
content: [
|
||||||
("SUMMARY".to_owned(), (vec![], "Test event".to_owned())),
|
("SUMMARY".to_owned(), vec![(vec![], "Test event".to_owned())]),
|
||||||
("DTSTART".to_owned(), (vec![("TZID".to_owned(), "Europe/Berlin".to_owned())], "19700101".to_owned()))
|
("DTSTART".to_owned(), vec![(vec![("TZID".to_owned(), "Europe/Berlin".to_owned())], "19700101".to_owned())])
|
||||||
].iter().cloned().collect(),
|
].iter().cloned().collect(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
}));
|
}));
|
||||||
|
@ -152,14 +184,14 @@ END:VEVENT
|
||||||
("DTSTART", "19700101")]
|
("DTSTART", "19700101")]
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|(k, v)| (k.to_owned(), (vec![], v.to_owned())))
|
.map(|(k, v)| (k.to_owned(), vec![(vec![], v.to_owned())]))
|
||||||
.collect(),
|
.collect(),
|
||||||
children: vec![Box::new(Object {
|
children: vec![Box::new(Object {
|
||||||
name: "VALARM".to_owned(),
|
name: "VALARM".to_owned(),
|
||||||
content: [("ACTION", "NONE")]
|
content: [("ACTION", "NONE")]
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|(k, v)| (k.to_owned(), (vec![], v.to_owned())))
|
.map(|(k, v)| (k.to_owned(), vec![(vec![], v.to_owned())]))
|
||||||
.collect(),
|
.collect(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
})],
|
})],
|
||||||
|
|
Loading…
Reference in New Issue