Rewrote the whole decoder
This commit is contained in:
parent
67e5953c24
commit
5e71a7d848
9 changed files with 406 additions and 470 deletions
|
@ -7,25 +7,25 @@ use super::error;
|
|||
|
||||
// ---- EXTENSIONS ---
|
||||
impl xml::QRead<Violation> for Violation {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Option<Self>, error::ParsingError> {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
impl xml::QRead<Property> for Property {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Option<Self>, error::ParsingError> {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
impl xml::QRead<PropertyRequest> for PropertyRequest {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Option<Self>, error::ParsingError> {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
impl xml::QRead<ResourceType> for ResourceType {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Option<Self>, error::ParsingError> {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ use quick_xml::name::PrefixDeclaration;
|
|||
use tokio::io::AsyncWrite;
|
||||
|
||||
use super::caltypes::*;
|
||||
use super::xml::{QWrite, IWrite, Writer};
|
||||
use super::types::{Extension, Node};
|
||||
use super::xml::{Node, QWrite, IWrite, Writer};
|
||||
use super::types::Extension;
|
||||
|
||||
const ICAL_DATETIME_FMT: &str = "%Y%m%dT%H%M%SZ";
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use chrono::{DateTime,Utc};
|
||||
use super::types as dav;
|
||||
use super::xml;
|
||||
|
||||
//@FIXME ACL (rfc3744) is missing, required
|
||||
//@FIXME Versioning (rfc3253) is missing, required
|
||||
|
@ -44,7 +45,7 @@ pub struct MkCalendar<E: dav::Extension>(pub dav::Set<E>);
|
|||
///
|
||||
/// <!ELEMENT mkcol-response (propstat+)>
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct MkCalendarResponse<E: dav::Extension, N: dav::Node<N>>(pub Vec<dav::PropStat<E,N>>);
|
||||
pub struct MkCalendarResponse<E: dav::Extension, N: xml::Node<N>>(pub Vec<dav::PropStat<E,N>>);
|
||||
|
||||
// --- (REPORT PART) ---
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,7 @@ use quick_xml::writer::ElementWriter;
|
|||
use quick_xml::name::PrefixDeclaration;
|
||||
use tokio::io::AsyncWrite;
|
||||
use super::types::*;
|
||||
use super::xml::{Writer,QWrite,IWrite};
|
||||
use super::xml::{Node, Writer,QWrite,IWrite};
|
||||
|
||||
|
||||
// --- XML ROOTS
|
||||
|
|
|
@ -2,6 +2,7 @@ use quick_xml::events::attributes::AttrError;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum ParsingError {
|
||||
Recoverable,
|
||||
MissingChild,
|
||||
NamespacePrefixAlreadyUsed,
|
||||
WrongToken,
|
||||
|
|
|
@ -6,8 +6,8 @@ use super::error;
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub struct Disabled(());
|
||||
impl xml::QRead<Disabled> for Disabled {
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Option<Self>, error::ParsingError> {
|
||||
Ok(None)
|
||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||
Err(error::ParsingError::Recoverable)
|
||||
}
|
||||
}
|
||||
impl xml::QWrite for Disabled {
|
||||
|
|
|
@ -7,12 +7,11 @@ use super::error;
|
|||
|
||||
/// It's how we implement a DAV extension
|
||||
/// (That's the dark magic part...)
|
||||
pub trait Node<T> = xml::QRead<T> + xml::QWrite + Debug + PartialEq;
|
||||
pub trait Extension {
|
||||
type Error: Node<Self::Error>;
|
||||
type Property: Node<Self::Property>;
|
||||
type PropertyRequest: Node<Self::PropertyRequest>;
|
||||
type ResourceType: Node<Self::ResourceType>;
|
||||
pub trait Extension: std::fmt::Debug + PartialEq {
|
||||
type Error: xml::Node<Self::Error>;
|
||||
type Property: xml::Node<Self::Property>;
|
||||
type PropertyRequest: xml::Node<Self::PropertyRequest>;
|
||||
type ResourceType: xml::Node<Self::ResourceType>;
|
||||
}
|
||||
|
||||
/// 14.1. activelock XML Element
|
||||
|
@ -333,7 +332,7 @@ pub enum LockType {
|
|||
///
|
||||
/// <!ELEMENT multistatus (response*, responsedescription?) >
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Multistatus<E: Extension, N: Node<N>> {
|
||||
pub struct Multistatus<E: Extension, N: xml::Node<N>> {
|
||||
pub responses: Vec<Response<E, N>>,
|
||||
pub responsedescription: Option<ResponseDescription>,
|
||||
}
|
||||
|
@ -465,7 +464,7 @@ pub enum PropFind<E: Extension> {
|
|||
///
|
||||
/// <!ELEMENT propstat (prop, status, error?, responsedescription?) >
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct PropStat<E: Extension, N: Node<N>> {
|
||||
pub struct PropStat<E: Extension, N: xml::Node<N>> {
|
||||
pub prop: N,
|
||||
pub status: Status,
|
||||
pub error: Option<Error<E>>,
|
||||
|
@ -514,7 +513,7 @@ pub struct Remove<E: Extension>(pub PropName<E>);
|
|||
/// --- rewritten as ---
|
||||
/// <!ELEMENT response ((href+, status)|(href, propstat+), error?, responsedescription?, location?>
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum StatusOrPropstat<E: Extension, N: Node<N>> {
|
||||
pub enum StatusOrPropstat<E: Extension, N: xml::Node<N>> {
|
||||
// One status, multiple hrefs...
|
||||
Status(Vec<Href>, Status),
|
||||
// A single href, multiple properties...
|
||||
|
@ -522,7 +521,7 @@ pub enum StatusOrPropstat<E: Extension, N: Node<N>> {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Response<E: Extension, N: Node<N>> {
|
||||
pub struct Response<E: Extension, N: xml::Node<N>> {
|
||||
pub status_or_propstat: StatusOrPropstat<E, N>,
|
||||
pub error: Option<Error<E>>,
|
||||
pub responsedescription: Option<ResponseDescription>,
|
||||
|
|
|
@ -19,9 +19,14 @@ pub trait QWrite {
|
|||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), quick_xml::Error>;
|
||||
}
|
||||
pub trait QRead<T> {
|
||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<T>, ParsingError>;
|
||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<T, ParsingError>;
|
||||
}
|
||||
|
||||
// The representation of an XML node in Rust
|
||||
pub trait Node<T> = QRead<T> + QWrite + std::fmt::Debug + PartialEq;
|
||||
|
||||
// ---------------
|
||||
|
||||
/// Transform a Rust object into an XML stream of characters
|
||||
pub struct Writer<T: IWrite> {
|
||||
pub q: quick_xml::writer::Writer<T>,
|
||||
|
@ -106,6 +111,8 @@ impl<T: IRead> Reader<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Disabled
|
||||
/// maybe find start tag
|
||||
pub async fn maybe_tag_start(&mut self, ns: &[u8], key: &str) -> Result<Option<Event<'static>>, ParsingError> {
|
||||
println!("maybe start tag {}", key);
|
||||
|
@ -118,7 +125,6 @@ impl<T: IRead> Reader<T> {
|
|||
|
||||
/// find start tag
|
||||
pub async fn tag_start(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
|
||||
println!("search start tag {}", key);
|
||||
loop {
|
||||
match self.peek() {
|
||||
Event::Start(b) if self.is_tag(ns, key) => break,
|
||||
|
@ -127,6 +133,7 @@ impl<T: IRead> Reader<T> {
|
|||
}
|
||||
self.next().await
|
||||
}
|
||||
*/
|
||||
|
||||
// find stop tag
|
||||
pub async fn tag_stop(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
|
||||
|
@ -157,5 +164,81 @@ impl<T: IRead> Reader<T> {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
// NEW API
|
||||
pub async fn maybe_read<N: Node<N>>(&mut self, t: &mut Option<N>, dirty: &mut bool) -> Result<(), ParsingError> {
|
||||
match N::qread(self).await {
|
||||
Ok(v) => {
|
||||
*t = Some(v);
|
||||
*dirty = true;
|
||||
Ok(())
|
||||
},
|
||||
Err(ParsingError::Recoverable) => Ok(()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn maybe_push<N: Node<N>>(&mut self, t: &mut Vec<N>, dirty: &mut bool) -> Result<(), ParsingError> {
|
||||
match N::qread(self).await {
|
||||
Ok(v) => {
|
||||
t.push(v);
|
||||
*dirty = true;
|
||||
Ok(())
|
||||
},
|
||||
Err(ParsingError::Recoverable) => Ok(()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn find<N: Node<N>>(&mut self) -> Result<N, ParsingError> {
|
||||
loop {
|
||||
// Try parse
|
||||
match N::qread(self).await {
|
||||
Err(ParsingError::Recoverable) => (),
|
||||
otherwise => return otherwise,
|
||||
}
|
||||
|
||||
// If recovered, skip the element
|
||||
self.skip().await?;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn maybe_find<N: Node<N>>(&mut self) -> Result<Option<N>, ParsingError> {
|
||||
loop {
|
||||
// Try parse
|
||||
match N::qread(self).await {
|
||||
Err(ParsingError::Recoverable) => (),
|
||||
otherwise => return otherwise.map(Some),
|
||||
}
|
||||
|
||||
match self.peek() {
|
||||
Event::End(_) => return Ok(None),
|
||||
_ => self.skip().await?,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn collect<N: Node<N>>(&mut self) -> Result<Vec<N>, ParsingError> {
|
||||
let mut acc = Vec::new();
|
||||
loop {
|
||||
match N::qread(self).await {
|
||||
Err(ParsingError::Recoverable) => match self.peek() {
|
||||
Event::End(_) => return Ok(acc),
|
||||
_ => {
|
||||
self.skip().await?;
|
||||
},
|
||||
},
|
||||
Ok(v) => acc.push(v),
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn open(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
|
||||
if self.is_tag(ns, key) {
|
||||
return self.next().await
|
||||
}
|
||||
return Err(ParsingError::Recoverable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue