From 6d1f538091ca9445cdc0d72b051fa5090b6ec68a Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Fri, 8 Mar 2024 22:03:46 +0100 Subject: Improve my XML parser --- aero-dav/src/caldecoder.rs | 40 ++++++++++++++++++++++++++++++++++++++++ aero-dav/src/xml.rs | 14 +++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/aero-dav/src/caldecoder.rs b/aero-dav/src/caldecoder.rs index 1a096c1..239b005 100644 --- a/aero-dav/src/caldecoder.rs +++ b/aero-dav/src/caldecoder.rs @@ -393,7 +393,9 @@ impl QRead for CompInner { impl QRead for CompSupport { async fn qread(xml: &mut Reader) -> Result { xml.open(CAL_URN, "comp").await?; + println!("before"); let inner = Component::new(xml.prev_attr("name").ok_or(ParsingError::MissingAttribute)?); + println!("after"); xml.close().await?; Ok(Self(inner)) } @@ -763,4 +765,42 @@ mod tests { let got = deserialize::>(src).await; assert_eq!(got, expected) } + + #[tokio::test] + async fn rfc_mkcalendar() { + let expected = MkCalendar(dav::Set(dav::PropValue(vec![ + dav::Property::DisplayName("Lisa's Events".into()), + dav::Property::Extension(Property::CalendarDescription { + lang: Some("en".into()), + text: "Calendar restricted to events.".into(), + }), + dav::Property::Extension(Property::SupportedCalendarComponentSet(vec![ + CompSupport(Component::VEvent) + ])), + dav::Property::Extension(Property::CalendarTimezone("BEGIN:VCALENDAR\nPRODID:-//Example Corp.//CalDAV Client//EN\nVERSION:2.0\nEND:VCALENDAR".into())), + ]))); + + let src = r#" + + + + + Lisa's Events + Calendar restricted to events. + + + + + + + "#; + + let got = deserialize::>(src).await; + assert_eq!(got, expected) + } } diff --git a/aero-dav/src/xml.rs b/aero-dav/src/xml.rs index e021543..347a123 100644 --- a/aero-dav/src/xml.rs +++ b/aero-dav/src/xml.rs @@ -236,12 +236,20 @@ impl Reader { pub async fn open(&mut self, ns: &[u8], key: &str) -> Result, ParsingError> { //println!("try open tag {:?}", key); let evt = match self.peek() { - Event::Empty(_) if self.is_tag(ns, key) => self.cur.clone(), + Event::Empty(_) if self.is_tag(ns, key) => { + // hack to make `prev_attr` works + // here we duplicate the current tag + // as in other words, we virtually moved one token + // which is useful for prev_attr and any logic based on + // self.prev + self.open() on empty nodes + self.prev = self.cur.clone(); + self.cur.clone() + }, Event::Start(_) if self.is_tag(ns, key) => self.next().await?, _ => return Err(ParsingError::Recoverable), }; - //println!("open tag {:?}", evt); + println!("open tag {:?}", evt); self.parents.push(evt.clone()); Ok(evt) } @@ -266,7 +274,7 @@ impl Reader { // find stop tag pub async fn close(&mut self) -> Result, ParsingError> { - //println!("close tag {:?}", self.parents.last()); + println!("close tag {:?}", self.parents.last()); // Handle the empty case if !self.parent_has_child() { -- cgit v1.2.3