Browse Source

ics: implement support for multiple values per key

master
Astro 3 months ago
parent
commit
7453b01191
2 changed files with 43 additions and 11 deletions
  1. 3
    3
      libticker/src/ics/mod.rs
  2. 40
    8
      libticker/src/ics/parser.rs

+ 3
- 3
libticker/src/ics/mod.rs View File

@@ -15,21 +15,21 @@ pub type Props = Vec<(String, String)>;
15 15
 #[derive(Debug, PartialEq)]
16 16
 pub struct Object {
17 17
     pub name: String,
18
-    pub content: HashMap<String, (Props, String)>,
18
+    pub content: HashMap<String, Vec<(Props, String)>>,
19 19
     pub children: Vec<Box<Object>>,
20 20
 }
21 21
 
22 22
 impl<'a> GetValue<'a, &'a str> for Object {
23 23
     fn get(&'a self, key: &'_ str) -> Option<&'a str> {
24 24
         self.content.get(key)
25
-            .map(|(_props, value)| value.as_ref())
25
+            .and_then(|pairs| pairs.first().map(|(_props, ref value)| value.as_str()))
26 26
     }
27 27
 }
28 28
 
29 29
 impl<'a> GetValue<'a, String> for Object {
30 30
     fn get(&self, key: &'_ str) -> Option<String> {
31 31
         self.content.get(key)
32
-            .map(|(_props, value)| value.clone())
32
+            .and_then(|pairs| pairs.first().map(|(_props, value)| value.clone()))
33 33
     }
34 34
 }
35 35
 

+ 40
- 8
libticker/src/ics/parser.rs View File

@@ -68,7 +68,10 @@ impl Parser {
68 68
                         let key = replace(current_key, None);
69 69
                         let objects_len = objects.len();
70 70
                         let content = &mut objects[objects_len - 1].content;
71
-                        key.map(|key| content.insert(key, (props, value)));
71
+                        key.map(|key| content.entry(key)
72
+                                .or_insert_with(|| vec![])
73
+                                .push((props, value))
74
+                        );
72 75
                     }
73 76
                 }
74 77
             }
@@ -87,7 +90,6 @@ mod test {
87 90
         p.feed(b"BEGIN:VEVENT
88 91
 SUMMARY:Test event
89 92
 DTSTART:19700101
90
-RRULE:FREQ=YEARLY
91 93
 END:VEVENT
92 94
 
93 95
 ", |o| {
@@ -97,11 +99,41 @@ END:VEVENT
97 99
         assert_eq!(obj, Some(Object {
98 100
             name: "VEVENT".to_owned(),
99 101
             content: [("SUMMARY", "Test event"),
100
-                      ("RRULE", "FREQ=YEARLY"),
101 102
                       ("DTSTART", "19700101")]
102 103
                 .iter()
103 104
                 .cloned()
104
-                .map(|(k, v)| (k.to_owned(), (vec![], v.to_owned())))
105
+                .map(|(k, v)| (k.to_owned(), vec![(vec![], v.to_owned())]))
106
+                .collect(),
107
+            children: vec![],
108
+        }));
109
+    }
110
+
111
+    #[test]
112
+    fn parse_recurring_event() {
113
+        let mut p = Parser::new();
114
+        let mut obj = None;
115
+        p.feed(b"BEGIN:VEVENT
116
+SUMMARY:Test event
117
+DTSTART:19700101
118
+RRULE:FREQ=YEARLY
119
+EXDATE:19710101
120
+EXDATE:19730101
121
+EXDATE:19770101
122
+END:VEVENT
123
+
124
+", |o| {
125
+    assert!(obj.is_none());
126
+    obj = Some(o);
127
+});
128
+        assert_eq!(obj, Some(Object {
129
+            name: "VEVENT".to_owned(),
130
+            content: [("SUMMARY", vec!["Test event"]),
131
+                      ("RRULE", vec!["FREQ=YEARLY"]),
132
+                      ("EXDATE", vec!["19710101", "19730101", "19770101"]),
133
+                      ("DTSTART", vec!["19700101"])]
134
+                .iter()
135
+                .cloned()
136
+                .map(|(k, v)| (k.to_owned(), v.into_iter().map(|v| (vec![], v.to_owned())).collect()))
105 137
                 .collect(),
106 138
             children: vec![],
107 139
         }));
@@ -123,8 +155,8 @@ END:VEVENT
123 155
         assert_eq!(obj, Some(Object {
124 156
             name: "VEVENT".to_owned(),
125 157
             content: [
126
-                ("SUMMARY".to_owned(), (vec![], "Test event".to_owned())),
127
-                ("DTSTART".to_owned(), (vec![("TZID".to_owned(), "Europe/Berlin".to_owned())], "19700101".to_owned()))
158
+                ("SUMMARY".to_owned(), vec![(vec![], "Test event".to_owned())]),
159
+                ("DTSTART".to_owned(), vec![(vec![("TZID".to_owned(), "Europe/Berlin".to_owned())], "19700101".to_owned())])
128 160
             ].iter().cloned().collect(),
129 161
             children: vec![],
130 162
         }));
@@ -152,14 +184,14 @@ END:VEVENT
152 184
                       ("DTSTART", "19700101")]
153 185
                 .iter()
154 186
                 .cloned()
155
-                .map(|(k, v)| (k.to_owned(), (vec![], v.to_owned())))
187
+                .map(|(k, v)| (k.to_owned(), vec![(vec![], v.to_owned())]))
156 188
                 .collect(),
157 189
             children: vec![Box::new(Object {
158 190
                 name: "VALARM".to_owned(),
159 191
                 content: [("ACTION", "NONE")]
160 192
                     .iter()
161 193
                     .cloned()
162
-                    .map(|(k, v)| (k.to_owned(), (vec![], v.to_owned())))
194
+                    .map(|(k, v)| (k.to_owned(), vec![(vec![], v.to_owned())]))
163 195
                     .collect(),
164 196
                 children: vec![],
165 197
             })],

Loading…
Cancel
Save