1 #![allow(unused)]
2
3 extern crate quick_xml;
4
5 use quick_xml::events::Event;
6 use quick_xml::Reader;
7 use std::io::Read;
8
9 struct Resource {
10 etag: String,
11 calendar_data: String,
12 }
13
14 struct Prop {
15 namespace: String,
16 local_name: String,
17 value: String,
18 }
19
20 impl Prop {
new() -> Prop21 fn new() -> Prop {
22 Prop {
23 namespace: String::new(),
24 local_name: String::new(),
25 value: String::new(),
26 }
27 }
28 }
29
30 struct PropStat {
31 status: String,
32 props: Vec<Prop>,
33 }
34
35 impl PropStat {
new() -> PropStat36 fn new() -> PropStat {
37 PropStat {
38 status: String::new(),
39 props: Vec::<Prop>::new(),
40 }
41 }
42 }
43
44 struct Response {
45 href: String,
46 propstats: Vec<PropStat>,
47 }
48
49 impl Response {
new() -> Response50 fn new() -> Response {
51 Response {
52 href: String::new(),
53 propstats: Vec::<PropStat>::new(),
54 }
55 }
56 }
57
parse_report(xml_data: &str) -> Vec<Resource>58 fn parse_report(xml_data: &str) -> Vec<Resource> {
59 let result = Vec::<Resource>::new();
60
61 let mut reader = Reader::from_str(xml_data);
62 reader.trim_text(true);
63
64 let mut count = 0;
65 let mut buf = Vec::new();
66 let mut ns_buffer = Vec::new();
67
68 #[derive(Clone, Copy)]
69 enum State {
70 Root,
71 MultiStatus,
72 Response,
73 Success,
74 Error,
75 };
76
77 let mut responses = Vec::<Response>::new();
78 let mut current_response = Response::new();
79 let mut current_prop = Prop::new();
80
81 let mut depth = 0;
82 let mut state = State::MultiStatus;
83
84 loop {
85 match reader.read_namespaced_event(&mut buf, &mut ns_buffer) {
86 Ok((namespace_value, Event::Start(e))) => {
87 let namespace_value = namespace_value.unwrap_or_default();
88 match (depth, state, namespace_value, e.local_name()) {
89 (0, State::Root, b"DAV:", b"multistatus") => state = State::MultiStatus,
90 (1, State::MultiStatus, b"DAV:", b"response") => {
91 state = State::Response;
92 current_response = Response::new();
93 }
94 (2, State::Response, b"DAV:", b"href") => {
95 current_response.href = e.unescape_and_decode(&reader).unwrap();
96 }
97 _ => {}
98 }
99 depth += 1;
100 }
101 Ok((namespace_value, Event::End(e))) => {
102 let namespace_value = namespace_value.unwrap_or_default();
103 let local_name = e.local_name();
104 match (depth, state, &*namespace_value, local_name) {
105 (1, State::MultiStatus, b"DAV:", b"multistatus") => state = State::Root,
106 (2, State::MultiStatus, b"DAV:", b"multistatus") => state = State::MultiStatus,
107 _ => {}
108 }
109 depth -= 1;
110 }
111 Ok((_, Event::Eof)) => break,
112 Err(e) => break,
113 _ => (),
114 }
115 }
116 result
117 }
118
main()119 fn main() {
120 let test_data = r#"
121 <?xml version="1.0" encoding="UTF-8"?>
122 <D:multistatus xmlns:D="DAV:" xmlns:caldav="urn:ietf:params:xml:ns:caldav"
123 xmlns:cs="http://calendarserver.org/ns/" xmlns:ical="http://apple.com/ns/ical/">
124 <D:response xmlns:carddav="urn:ietf:params:xml:ns:carddav"
125 xmlns:cm="http://cal.me.com/_namespace/" xmlns:md="urn:mobileme:davservices">
126 <D:href>
127 /caldav/v2/johndoh%40gmail.com/events/07b7it7uonpnlnvjldr0l1ckg8%40google.com.ics
128 </D:href>
129 <D:propstat>
130 <D:status>HTTP/1.1 200 OK</D:status>
131 <D:prop>
132 <D:getetag>"63576798396"</D:getetag>
133 <caldav:calendar-data>BEGIN:VCALENDAR</caldav:calendar-data>
134 </D:prop>
135 </D:propstat>
136 </D:response>
137 </D:multistatus>
138 "#;
139
140 parse_report(test_data);
141 }
142