1
use crate::model::property::RecurrenceDateTimesPropertyValue;
2
use crate::serialize::WriteModel;
3
use std::io::Write;
4

            
5
impl WriteModel for crate::model::property::ComponentProperty {
6
672
    fn write_model<W: Write>(&self, writer: &mut W) -> anyhow::Result<()> {
7
672
        use crate::model::property::ComponentProperty;
8
672

            
9
672
        match self {
10
30
            ComponentProperty::DateTimeStamp(property) => {
11
30
                writer.write_all(b"DTSTAMP")?;
12
30
                property.params.as_slice().write_model(writer)?;
13
30
                writer.write_all(b":")?;
14
30
                property.value.write_model(writer)?;
15
            }
16
28
            ComponentProperty::UniqueIdentifier(property) => {
17
28
                writer.write_all(b"UID")?;
18
28
                property.params.as_slice().write_model(writer)?;
19
28
                writer.write_all(b":")?;
20
28
                property.value.write_model(writer)?;
21
            }
22
60
            ComponentProperty::DateTimeStart(property) => {
23
60
                writer.write_all(b"DTSTART")?;
24
60
                property.params.as_slice().write_model(writer)?;
25
60
                writer.write_all(b":")?;
26
60
                property.value.write_model(writer)?;
27
            }
28
14
            ComponentProperty::Classification(property) => {
29
14
                writer.write_all(b"CLASS")?;
30
14
                property.params.as_slice().write_model(writer)?;
31
14
                writer.write_all(b":")?;
32
14
                property.value.write_model(writer)?;
33
            }
34
6
            ComponentProperty::DateTimeCreated(property) => {
35
6
                writer.write_all(b"CREATED")?;
36
6
                property.params.as_slice().write_model(writer)?;
37
6
                writer.write_all(b":")?;
38
6
                property.value.write_model(writer)?;
39
            }
40
18
            ComponentProperty::Description(property) => {
41
18
                writer.write_all(b"DESCRIPTION")?;
42
18
                property.params.as_slice().write_model(writer)?;
43
18
                writer.write_all(b":")?;
44
18
                property.value.write_model(writer)?;
45
            }
46
4
            ComponentProperty::GeographicPosition(property) => {
47
4
                writer.write_all(b"GEO")?;
48
4
                property.params.as_slice().write_model(writer)?;
49
4
                writer.write_all(b":")?;
50
4
                write!(writer, "{};", property.value.latitude)?;
51
4
                write!(writer, "{}", property.value.longitude)?;
52
            }
53
18
            ComponentProperty::LastModified(property) => {
54
18
                writer.write_all(b"LAST-MODIFIED")?;
55
18
                property.params.as_slice().write_model(writer)?;
56
18
                writer.write_all(b":")?;
57
18
                property.value.write_model(writer)?;
58
            }
59
4
            ComponentProperty::Location(property) => {
60
4
                writer.write_all(b"LOCATION")?;
61
4
                property.params.as_slice().write_model(writer)?;
62
4
                writer.write_all(b":")?;
63
4
                property.value.write_model(writer)?;
64
            }
65
14
            ComponentProperty::Organizer(property) => {
66
14
                writer.write_all(b"ORGANIZER")?;
67
14
                property.params.as_slice().write_model(writer)?;
68
14
                writer.write_all(b":")?;
69
14
                writer.write_all(property.value.as_bytes())?;
70
            }
71
6
            ComponentProperty::Priority(property) => {
72
6
                writer.write_all(b"PRIORITY")?;
73
6
                property.params.as_slice().write_model(writer)?;
74
6
                writer.write_all(b":")?;
75
6
                write!(writer, "{}", property.value)?;
76
            }
77
6
            ComponentProperty::Sequence(property) => {
78
6
                writer.write_all(b"SEQUENCE")?;
79
6
                property.params.as_slice().write_model(writer)?;
80
6
                writer.write_all(b":")?;
81
6
                write!(writer, "{}", property.value)?;
82
            }
83
24
            ComponentProperty::Summary(property) => {
84
24
                writer.write_all(b"SUMMARY")?;
85
24
                property.params.as_slice().write_model(writer)?;
86
24
                writer.write_all(b":")?;
87
24
                property.value.write_model(writer)?;
88
            }
89
8
            ComponentProperty::TimeTransparency(property) => {
90
8
                writer.write_all(b"TRANSP")?;
91
8
                property.params.as_slice().write_model(writer)?;
92
8
                writer.write_all(b":")?;
93
8
                property.value.write_model(writer)?;
94
            }
95
8
            ComponentProperty::RequestStatus(property) => {
96
8
                writer.write_all(b"REQUEST-STATUS")?;
97
8
                property.params.as_slice().write_model(writer)?;
98
8
                writer.write_all(b":")?;
99
8
                if let Some(code) = property.value.status_code.first() {
100
8
                    write!(writer, "{}", code)?;
101
                }
102
8
                for code in property.value.status_code.iter().skip(1) {
103
8
                    write!(writer, ".{}", code)?;
104
                }
105
8
                writer.write_all(b";")?;
106
8
                writer.write_all(property.value.description.as_bytes())?;
107
8
                if let Some(exception_data) = &property.value.exception_data {
108
8
                    writer.write_all(b";")?;
109
8
                    writer.write_all(exception_data.as_bytes())?;
110
                }
111
            }
112
12
            ComponentProperty::Url(property) => {
113
12
                writer.write_all(b"URL")?;
114
12
                property.params.as_slice().write_model(writer)?;
115
12
                writer.write_all(b":")?;
116
12
                writer.write_all(property.value.as_bytes())?;
117
            }
118
6
            ComponentProperty::RecurrenceId(property) => {
119
6
                writer.write_all(b"RECURRENCE-ID")?;
120
6
                property.params.as_slice().write_model(writer)?;
121
6
                writer.write_all(b":")?;
122
6
                property.value.write_model(writer)?;
123
            }
124
38
            ComponentProperty::RecurrenceRule(property) => {
125
38
                writer.write_all(b"RRULE")?;
126
38
                property.params.as_slice().write_model(writer)?;
127
38
                writer.write_all(b":")?;
128
38
                property.value.write_model(writer)?;
129
            }
130
14
            ComponentProperty::DateTimeEnd(property) => {
131
14
                writer.write_all(b"DTEND")?;
132
14
                property.params.as_slice().write_model(writer)?;
133
14
                writer.write_all(b":")?;
134
14
                property.value.write_model(writer)?;
135
            }
136
14
            ComponentProperty::Duration(property) => {
137
14
                writer.write_all(b"DURATION")?;
138
14
                property.params.as_slice().write_model(writer)?;
139
14
                writer.write_all(b":")?;
140
14
                property.value.write_model(writer)?;
141
            }
142
14
            ComponentProperty::Attach(property) => {
143
14
                writer.write_all(b"ATTACH")?;
144
14
                property.params.as_slice().write_model(writer)?;
145
14
                writer.write_all(b":")?;
146
14
                writer.write_all(property.value.as_bytes())?;
147
            }
148
16
            ComponentProperty::Attendee(property) => {
149
16
                writer.write_all(b"ATTENDEE")?;
150
16
                property.params.as_slice().write_model(writer)?;
151
16
                writer.write_all(b":")?;
152
16
                writer.write_all(property.value.as_bytes())?;
153
            }
154
14
            ComponentProperty::Categories(property) => {
155
14
                writer.write_all(b"CATEGORIES")?;
156
14
                property.params.as_slice().write_model(writer)?;
157
14
                writer.write_all(b":")?;
158
14
                if let Some(category) = property.value.first() {
159
14
                    category.write_model(writer)?;
160
                }
161
22
                for category in property.value.iter().skip(1) {
162
22
                    writer.write_all(b",")?;
163
22
                    category.write_model(writer)?;
164
                }
165
            }
166
14
            ComponentProperty::Comment(property) => {
167
14
                writer.write_all(b"COMMENT")?;
168
14
                property.params.as_slice().write_model(writer)?;
169
14
                writer.write_all(b":")?;
170
14
                property.value.write_model(writer)?;
171
            }
172
8
            ComponentProperty::Contact(property) => {
173
8
                writer.write_all(b"CONTACT")?;
174
8
                property.params.as_slice().write_model(writer)?;
175
8
                writer.write_all(b":")?;
176
8
                property.value.write_model(writer)?;
177
            }
178
6
            ComponentProperty::ExceptionDateTimes(property) => {
179
6
                writer.write_all(b"EXDATE")?;
180
6
                property.params.as_slice().write_model(writer)?;
181
6
                writer.write_all(b":")?;
182
6
                if let Some(dt) = property.value.first() {
183
6
                    dt.write_model(writer)?;
184
                }
185
6
                for dt in property.value.iter().skip(1) {
186
6
                    writer.write_all(b",")?;
187
6
                    dt.write_model(writer)?;
188
                }
189
            }
190
10
            ComponentProperty::Status(property) => {
191
10
                writer.write_all(b"STATUS")?;
192
10
                property.params.as_slice().write_model(writer)?;
193
10
                writer.write_all(b":")?;
194
10
                property.value.write_model(writer)?;
195
            }
196
6
            ComponentProperty::RelatedTo(property) => {
197
6
                writer.write_all(b"RELATED-TO")?;
198
6
                property.params.as_slice().write_model(writer)?;
199
6
                writer.write_all(b":")?;
200
6
                property.value.write_model(writer)?;
201
            }
202
4
            ComponentProperty::Resources(property) => {
203
4
                writer.write_all(b"RESOURCES")?;
204
4
                property.params.as_slice().write_model(writer)?;
205
4
                writer.write_all(b":")?;
206
4
                if let Some(resource) = property.value.first() {
207
4
                    resource.write_model(writer)?;
208
                }
209
8
                for resource in property.value.iter().skip(1) {
210
8
                    writer.write_all(b",")?;
211
8
                    resource.write_model(writer)?;
212
                }
213
            }
214
12
            ComponentProperty::RecurrenceDateTimes(property) => {
215
12
                writer.write_all(b"RDATE")?;
216
12
                property.params.as_slice().write_model(writer)?;
217
12
                writer.write_all(b":")?;
218
12
                match &property.value {
219
12
                    RecurrenceDateTimesPropertyValue::DateTimes(date_times) => {
220
12
                        if let Some(dt) = date_times.first() {
221
12
                            dt.write_model(writer)?;
222
                        }
223
12
                        for dt in date_times.iter().skip(1) {
224
10
                            writer.write_all(b",")?;
225
10
                            dt.write_model(writer)?;
226
                        }
227
                    }
228
                    RecurrenceDateTimesPropertyValue::Periods(periods) => {
229
                        if let Some(period) = periods.first() {
230
                            period.write_model(writer)?;
231
                        }
232
                        for period in periods.iter().skip(1) {
233
                            writer.write_all(b",")?;
234
                            period.write_model(writer)?;
235
                        }
236
                    }
237
                }
238
            }
239
4
            ComponentProperty::DateTimeCompleted(property) => {
240
4
                writer.write_all(b"COMPLETED")?;
241
4
                property.params.as_slice().write_model(writer)?;
242
4
                writer.write_all(b":")?;
243
4
                property.value.write_model(writer)?;
244
            }
245
2
            ComponentProperty::PercentComplete(property) => {
246
2
                writer.write_all(b"PERCENT-COMPLETE")?;
247
2
                property.params.as_slice().write_model(writer)?;
248
2
                writer.write_all(b":")?;
249
2
                write!(writer, "{}", property.value)?;
250
            }
251
4
            ComponentProperty::DateTimeDue(property) => {
252
4
                writer.write_all(b"DUE")?;
253
4
                property.params.as_slice().write_model(writer)?;
254
4
                writer.write_all(b":")?;
255
4
                property.value.write_model(writer)?;
256
            }
257
10
            ComponentProperty::FreeBusyTime(property) => {
258
10
                writer.write_all(b"FREEBUSY")?;
259
10
                property.params.as_slice().write_model(writer)?;
260
10
                writer.write_all(b":")?;
261
10
                if let Some(period) = property.value.first() {
262
10
                    period.write_model(writer)?;
263
                }
264
10
                for period in property.value.iter().skip(1) {
265
6
                    writer.write_all(b",")?;
266
6
                    period.write_model(writer)?;
267
                }
268
            }
269
12
            ComponentProperty::TimeZoneId(property) => {
270
12
                writer.write_all(b"TZID")?;
271
12
                property.params.as_slice().write_model(writer)?;
272
12
                writer.write_all(b":")?;
273
12
                if property.value.unique_registry_id {
274
                    writer.write_all(b"/")?;
275
12
                }
276
12
                writer.write_all(property.value.id.as_bytes())?;
277
            }
278
4
            ComponentProperty::TimeZoneUrl(property) => {
279
4
                writer.write_all(b"TZURL")?;
280
4
                property.params.as_slice().write_model(writer)?;
281
4
                writer.write_all(b":")?;
282
4
                writer.write_all(property.value.as_bytes())?;
283
            }
284
36
            ComponentProperty::TimeZoneOffsetTo(property) => {
285
36
                writer.write_all(b"TZOFFSETTO")?;
286
36
                property.params.as_slice().write_model(writer)?;
287
36
                writer.write_all(b":")?;
288
36
                property.value.write_model(writer)?;
289
            }
290
36
            ComponentProperty::TimeZoneOffsetFrom(property) => {
291
36
                writer.write_all(b"TZOFFSETFROM")?;
292
36
                property.params.as_slice().write_model(writer)?;
293
36
                writer.write_all(b":")?;
294
36
                property.value.write_model(writer)?;
295
            }
296
36
            ComponentProperty::TimeZoneName(property) => {
297
36
                writer.write_all(b"TZNAME")?;
298
36
                property.params.as_slice().write_model(writer)?;
299
36
                writer.write_all(b":")?;
300
36
                property.value.write_model(writer)?;
301
            }
302
14
            ComponentProperty::Action(property) => {
303
14
                writer.write_all(b"ACTION")?;
304
14
                property.params.as_slice().write_model(writer)?;
305
14
                writer.write_all(b":")?;
306
14
                property.value.write_model(writer)?;
307
            }
308
14
            ComponentProperty::Trigger(property) => {
309
14
                writer.write_all(b"TRIGGER")?;
310
14
                match &property.value {
311
8
                    crate::model::property::TriggerValue::Relative(duration) => {
312
8
                        property.params.as_slice().write_model(writer)?;
313
8
                        writer.write_all(b":")?;
314
8
                        duration.write_model(writer)?;
315
                    }
316
6
                    crate::model::property::TriggerValue::Absolute(date_time) => {
317
6
                        property.params.as_slice().write_model(writer)?;
318
6
                        writer.write_all(b":")?;
319
6
                        date_time.write_model(writer)?;
320
                    }
321
                }
322
            }
323
12
            ComponentProperty::Repeat(property) => {
324
12
                writer.write_all(b"REPEAT")?;
325
12
                property.params.as_slice().write_model(writer)?;
326
12
                writer.write_all(b":")?;
327
12
                write!(writer, "{}", property.value)?;
328
            }
329
26
            ComponentProperty::IanaProperty(property) => {
330
26
                writer.write_all(property.name.as_bytes())?;
331
26
                property.params.as_slice().write_model(writer)?;
332
26
                writer.write_all(b":")?;
333
26
                writer.write_all(property.value.as_bytes())?;
334
            }
335
26
            ComponentProperty::XProperty(property) => {
336
26
                writer.write_all(property.name.as_bytes())?;
337
26
                property.params.as_slice().write_model(writer)?;
338
26
                writer.write_all(b":")?;
339
26
                writer.write_all(property.value.as_bytes())?;
340
            }
341
        }
342

            
343
672
        Ok(())
344
672
    }
345
}
346

            
347
impl WriteModel for &[crate::model::param::Param] {
348
680
    fn write_model<W: Write>(&self, writer: &mut W) -> anyhow::Result<()> {
349
1172
        for param in self.iter() {
350
836
            writer.write_all(b";")?;
351
836
            param.write_model(writer)?;
352
        }
353

            
354
680
        Ok(())
355
680
    }
356
}