Fixed some parsing bugs
This commit is contained in:
parent
b9f32d720a
commit
4d65366ff3
6 changed files with 206 additions and 152 deletions
|
@ -9,6 +9,7 @@ use quick_xml::reader::NsReader;
|
|||
use tokio::runtime::Runtime;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
// Split this file
|
||||
const tokens: [&str; 63] = [
|
||||
"0",
|
||||
"1",
|
||||
|
@ -125,6 +126,9 @@ impl Tag {
|
|||
|
||||
#[derive(Arbitrary)]
|
||||
enum XmlNode {
|
||||
//@FIXME: build RFC3339 and RFC822 Dates with chrono based on timestamps
|
||||
//@FIXME: add small numbers
|
||||
//@FIXME: add http status code
|
||||
Node(Tag, Vec<Self>),
|
||||
Number(u64),
|
||||
Text(Token),
|
||||
|
|
|
@ -1,9 +1,39 @@
|
|||
//use super::types as dav;
|
||||
use super::types as dav;
|
||||
use super::caltypes::*;
|
||||
use super::xml;
|
||||
use super::error;
|
||||
|
||||
// ---- ROOT ELEMENTS ---
|
||||
impl<E: dav::Extension> xml::QRead<MkCalendar<E>> for MkCalendar<E> {
|
||||
async fn qread(_xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: dav::Extension, N: xml::Node<N>> xml::QRead<MkCalendarResponse<E,N>> for MkCalendarResponse<E,N> {
|
||||
async fn qread(_xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: dav::Extension> xml::QRead<CalendarQuery<E>> for CalendarQuery<E> {
|
||||
async fn qread(_xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: dav::Extension> xml::QRead<CalendarMultiget<E>> for CalendarMultiget<E> {
|
||||
async fn qread(_xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
impl xml::QRead<FreeBusyQuery> for FreeBusyQuery {
|
||||
async fn qread(_xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- EXTENSIONS ---
|
||||
impl xml::QRead<Violation> for Violation {
|
||||
|
@ -31,3 +61,8 @@ impl xml::QRead<ResourceType> for ResourceType {
|
|||
}
|
||||
|
||||
// ---- INNER XML ----
|
||||
impl xml::QRead<SupportedCollation> for SupportedCollation {
|
||||
async fn qread(_xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -666,7 +666,7 @@ mod tests {
|
|||
use crate::types as dav;
|
||||
use crate::realization::Calendar;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use chrono::{Utc,TimeZone,DateTime};
|
||||
use chrono::{Utc,TimeZone};
|
||||
|
||||
async fn serialize(elem: &impl QWrite) -> String {
|
||||
let mut buffer = Vec::new();
|
||||
|
|
|
@ -23,8 +23,8 @@ impl<E: Extension> QRead<PropFind<E>> for PropFind<E> {
|
|||
let propfind: PropFind<E> = loop {
|
||||
// allprop
|
||||
if let Some(_) = xml.maybe_open(DAV_URN, "allprop").await? {
|
||||
let includ = xml.maybe_find::<Include<E>>().await?;
|
||||
xml.close().await?;
|
||||
let includ = xml.maybe_find::<Include<E>>().await?;
|
||||
break PropFind::AllProp(includ)
|
||||
}
|
||||
|
||||
|
@ -594,8 +594,9 @@ impl QRead<Href> for Href {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::{FixedOffset, DateTime, TimeZone, Utc};
|
||||
use chrono::{FixedOffset, TimeZone};
|
||||
use crate::realization::Core;
|
||||
use quick_xml::reader::NsReader;
|
||||
|
||||
#[tokio::test]
|
||||
async fn basic_propfind_propname() {
|
||||
|
@ -910,7 +911,7 @@ mod tests {
|
|||
Property::GetContentType("text/html".into()),
|
||||
Property::GetEtag(r#""zzyzx""#.into()),
|
||||
Property::GetLastModified(FixedOffset::west_opt(0).unwrap().with_ymd_and_hms(1998, 01, 12, 09, 25, 56).unwrap()),
|
||||
//Property::ResourceType(vec![]),
|
||||
Property::ResourceType(vec![]),
|
||||
Property::SupportedLock(vec![
|
||||
LockEntry {
|
||||
lockscope: LockScope::Exclusive,
|
||||
|
|
|
@ -633,6 +633,7 @@ impl<E: Extension> QWrite for Violation<E> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::super::xml;
|
||||
use crate::realization::Core;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
|
@ -653,43 +654,47 @@ mod tests {
|
|||
return got.into()
|
||||
}
|
||||
|
||||
async fn deserialize<T: xml::Node<T>>(src: &str) -> T {
|
||||
let mut rdr = xml::Reader::new(quick_xml::reader::NsReader::from_reader(src.as_bytes())).await.unwrap();
|
||||
rdr.find().await.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn basic_href() {
|
||||
let orig = Href("/SOGo/dav/so/".into());
|
||||
|
||||
let got = serialize(
|
||||
&Href("/SOGo/dav/so/".into())
|
||||
).await;
|
||||
let got = serialize(&orig).await;
|
||||
let expected = r#"<D:href xmlns:D="DAV:">/SOGo/dav/so/</D:href>"#;
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<Href>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn basic_multistatus() {
|
||||
let got = serialize(
|
||||
&Multistatus::<Core, PropName<Core>> {
|
||||
let orig = Multistatus::<Core, PropName<Core>> {
|
||||
responses: vec![],
|
||||
responsedescription: Some(ResponseDescription("Hello world".into()))
|
||||
},
|
||||
).await;
|
||||
};
|
||||
let got = serialize(&orig).await;
|
||||
|
||||
let expected = r#"<D:multistatus xmlns:D="DAV:">
|
||||
<D:responsedescription>Hello world</D:responsedescription>
|
||||
</D:multistatus>"#;
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<Multistatus::<Core, PropName<Core>>>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
|
||||
#[tokio::test]
|
||||
async fn rfc_error_delete_locked() {
|
||||
let got = serialize(
|
||||
&Error::<Core>(vec![
|
||||
let orig = Error::<Core>(vec![
|
||||
Violation::LockTokenSubmitted(vec![
|
||||
Href("/locked/".into())
|
||||
])
|
||||
]),
|
||||
).await;
|
||||
]);
|
||||
let got = serialize(&orig).await;
|
||||
|
||||
let expected = r#"<D:error xmlns:D="DAV:">
|
||||
<D:lock-token-submitted>
|
||||
|
@ -698,25 +703,26 @@ mod tests {
|
|||
</D:error>"#;
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<Error<Core>>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rfc_propname_req() {
|
||||
let got = serialize(
|
||||
&PropFind::<Core>::PropName,
|
||||
).await;
|
||||
let orig = PropFind::<Core>::PropName;
|
||||
|
||||
let got = serialize(&orig).await;
|
||||
|
||||
let expected = r#"<D:propfind xmlns:D="DAV:">
|
||||
<D:propname/>
|
||||
</D:propfind>"#;
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<PropFind::<Core>>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rfc_propname_res() {
|
||||
let got = serialize(
|
||||
&Multistatus::<Core, PropName<Core>> {
|
||||
let orig = Multistatus::<Core, PropName<Core>> {
|
||||
responses: vec![
|
||||
Response {
|
||||
status_or_propstat: StatusOrPropstat::PropStat(
|
||||
|
@ -762,8 +768,9 @@ mod tests {
|
|||
},
|
||||
],
|
||||
responsedescription: None,
|
||||
},
|
||||
).await;
|
||||
};
|
||||
|
||||
let got = serialize(&orig).await;
|
||||
|
||||
let expected = r#"<D:multistatus xmlns:D="DAV:">
|
||||
<D:response>
|
||||
|
@ -798,26 +805,27 @@ mod tests {
|
|||
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<Multistatus::<Core, PropName<Core>>>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rfc_allprop_req() {
|
||||
let got = serialize(
|
||||
&PropFind::<Core>::AllProp(None),
|
||||
).await;
|
||||
let orig = PropFind::<Core>::AllProp(None);
|
||||
let got = serialize(&orig).await;
|
||||
|
||||
let expected = r#"<D:propfind xmlns:D="DAV:">
|
||||
<D:allprop/>
|
||||
</D:propfind>"#;
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<PropFind::<Core>>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rfc_allprop_res() {
|
||||
use chrono::{DateTime,FixedOffset,TimeZone};
|
||||
let got = serialize(
|
||||
&Multistatus::<Core, PropValue<Core>> {
|
||||
use chrono::{FixedOffset,TimeZone};
|
||||
|
||||
let orig = Multistatus::<Core, PropValue<Core>> {
|
||||
responses: vec![
|
||||
Response {
|
||||
status_or_propstat: StatusOrPropstat::PropStat(
|
||||
|
@ -890,8 +898,9 @@ mod tests {
|
|||
},
|
||||
],
|
||||
responsedescription: None,
|
||||
}
|
||||
).await;
|
||||
};
|
||||
|
||||
let got = serialize(&orig).await;
|
||||
|
||||
let expected = r#"<D:multistatus xmlns:D="DAV:">
|
||||
<D:response>
|
||||
|
@ -961,16 +970,17 @@ mod tests {
|
|||
</D:multistatus>"#;
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<Multistatus::<Core, PropValue<Core>>>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rfc_allprop_include() {
|
||||
let got = serialize(
|
||||
&PropFind::<Core>::AllProp(Some(Include(vec![
|
||||
let orig = PropFind::<Core>::AllProp(Some(Include(vec![
|
||||
PropertyRequest::DisplayName,
|
||||
PropertyRequest::ResourceType,
|
||||
]))),
|
||||
).await;
|
||||
])));
|
||||
|
||||
let got = serialize(&orig).await;
|
||||
|
||||
let expected = r#"<D:propfind xmlns:D="DAV:">
|
||||
<D:allprop/>
|
||||
|
@ -981,6 +991,7 @@ mod tests {
|
|||
</D:propfind>"#;
|
||||
|
||||
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
|
||||
assert_eq!(deserialize::<PropFind::<Core>>(got.as_str()).await, orig)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
|
|
@ -79,7 +79,7 @@ impl<T: IRead> Reader<T> {
|
|||
/// skip a node at current level
|
||||
/// I would like to make this one private but not ready
|
||||
pub async fn skip(&mut self) -> Result<Event<'static>, ParsingError> {
|
||||
//println!("skipping inside node {:?}", self.parents.last());
|
||||
//println!("skipping inside node {:?} value {:?}", self.parents.last(), self.cur);
|
||||
match &self.cur {
|
||||
Event::Start(b) => {
|
||||
let _span = self.rdr.read_to_end_into_async(b.to_end().name(), &mut self.buf).await?;
|
||||
|
@ -212,8 +212,10 @@ impl<T: IRead> Reader<T> {
|
|||
}
|
||||
|
||||
pub async fn collect<N: Node<N>>(&mut self) -> Result<Vec<N>, ParsingError> {
|
||||
self.ensure_parent_has_child()?;
|
||||
let mut acc = Vec::new();
|
||||
if !self.parent_has_child() {
|
||||
return Ok(acc)
|
||||
}
|
||||
|
||||
loop {
|
||||
match N::qread(self).await {
|
||||
|
@ -230,6 +232,7 @@ impl<T: IRead> Reader<T> {
|
|||
}
|
||||
|
||||
pub async fn open(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
|
||||
//println!("try open tag {:?}", key);
|
||||
let evt = match self.peek() {
|
||||
Event::Empty(_) if self.is_tag(ns, key) => self.cur.clone(),
|
||||
Event::Start(_) if self.is_tag(ns, key) => self.next().await?,
|
||||
|
|
Loading…
Reference in a new issue