Improve my XML parser

This commit is contained in:
Quentin 2024-03-08 22:03:46 +01:00
parent f50f6d68aa
commit 6d1f538091
Signed by: quentin
GPG key ID: E9602264D639FF68
2 changed files with 51 additions and 3 deletions

View file

@ -393,7 +393,9 @@ impl QRead<CompInner> for CompInner {
impl QRead<CompSupport> for CompSupport { impl QRead<CompSupport> for CompSupport {
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> { async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
xml.open(CAL_URN, "comp").await?; xml.open(CAL_URN, "comp").await?;
println!("before");
let inner = Component::new(xml.prev_attr("name").ok_or(ParsingError::MissingAttribute)?); let inner = Component::new(xml.prev_attr("name").ok_or(ParsingError::MissingAttribute)?);
println!("after");
xml.close().await?; xml.close().await?;
Ok(Self(inner)) Ok(Self(inner))
} }
@ -763,4 +765,42 @@ mod tests {
let got = deserialize::<MkCalendar<Calendar>>(src).await; let got = deserialize::<MkCalendar<Calendar>>(src).await;
assert_eq!(got, expected) 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#"
<?xml version="1.0" encoding="utf-8" ?>
<C:mkcalendar xmlns:D="DAV:"
xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:set>
<D:prop>
<D:displayname>Lisa's Events</D:displayname>
<C:calendar-description xml:lang="en"
>Calendar restricted to events.</C:calendar-description>
<C:supported-calendar-component-set>
<C:comp name="VEVENT"/>
</C:supported-calendar-component-set>
<C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
PRODID:-//Example Corp.//CalDAV Client//EN
VERSION:2.0
END:VCALENDAR]]></C:calendar-timezone>
</D:prop>
</D:set>
</C:mkcalendar>"#;
let got = deserialize::<MkCalendar<Calendar>>(src).await;
assert_eq!(got, expected)
}
} }

View file

@ -236,12 +236,20 @@ impl<T: IRead> Reader<T> {
pub async fn open(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> { pub async fn open(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
//println!("try open tag {:?}", key); //println!("try open tag {:?}", key);
let evt = match self.peek() { 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?, Event::Start(_) if self.is_tag(ns, key) => self.next().await?,
_ => return Err(ParsingError::Recoverable), _ => return Err(ParsingError::Recoverable),
}; };
//println!("open tag {:?}", evt); println!("open tag {:?}", evt);
self.parents.push(evt.clone()); self.parents.push(evt.clone());
Ok(evt) Ok(evt)
} }
@ -266,7 +274,7 @@ impl<T: IRead> Reader<T> {
// find stop tag // find stop tag
pub async fn close(&mut self) -> Result<Event<'static>, ParsingError> { pub async fn close(&mut self) -> Result<Event<'static>, ParsingError> {
//println!("close tag {:?}", self.parents.last()); println!("close tag {:?}", self.parents.last());
// Handle the empty case // Handle the empty case
if !self.parent_has_child() { if !self.parent_has_child() {