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 ---
|
// ---- EXTENSIONS ---
|
||||||
impl xml::QRead<Violation> for Violation {
|
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!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl xml::QRead<Property> for Property {
|
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!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl xml::QRead<PropertyRequest> for PropertyRequest {
|
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!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl xml::QRead<ResourceType> for ResourceType {
|
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!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ use quick_xml::name::PrefixDeclaration;
|
||||||
use tokio::io::AsyncWrite;
|
use tokio::io::AsyncWrite;
|
||||||
|
|
||||||
use super::caltypes::*;
|
use super::caltypes::*;
|
||||||
use super::xml::{QWrite, IWrite, Writer};
|
use super::xml::{Node, QWrite, IWrite, Writer};
|
||||||
use super::types::{Extension, Node};
|
use super::types::Extension;
|
||||||
|
|
||||||
const ICAL_DATETIME_FMT: &str = "%Y%m%dT%H%M%SZ";
|
const ICAL_DATETIME_FMT: &str = "%Y%m%dT%H%M%SZ";
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use chrono::{DateTime,Utc};
|
use chrono::{DateTime,Utc};
|
||||||
use super::types as dav;
|
use super::types as dav;
|
||||||
|
use super::xml;
|
||||||
|
|
||||||
//@FIXME ACL (rfc3744) is missing, required
|
//@FIXME ACL (rfc3744) is missing, required
|
||||||
//@FIXME Versioning (rfc3253) 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+)>
|
/// <!ELEMENT mkcol-response (propstat+)>
|
||||||
#[derive(Debug, PartialEq)]
|
#[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) ---
|
// --- (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 quick_xml::name::PrefixDeclaration;
|
||||||
use tokio::io::AsyncWrite;
|
use tokio::io::AsyncWrite;
|
||||||
use super::types::*;
|
use super::types::*;
|
||||||
use super::xml::{Writer,QWrite,IWrite};
|
use super::xml::{Node, Writer,QWrite,IWrite};
|
||||||
|
|
||||||
|
|
||||||
// --- XML ROOTS
|
// --- XML ROOTS
|
||||||
|
|
|
@ -2,6 +2,7 @@ use quick_xml::events::attributes::AttrError;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ParsingError {
|
pub enum ParsingError {
|
||||||
|
Recoverable,
|
||||||
MissingChild,
|
MissingChild,
|
||||||
NamespacePrefixAlreadyUsed,
|
NamespacePrefixAlreadyUsed,
|
||||||
WrongToken,
|
WrongToken,
|
||||||
|
|
|
@ -6,8 +6,8 @@ use super::error;
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Disabled(());
|
pub struct Disabled(());
|
||||||
impl xml::QRead<Disabled> for Disabled {
|
impl xml::QRead<Disabled> for Disabled {
|
||||||
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> {
|
||||||
Ok(None)
|
Err(error::ParsingError::Recoverable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl xml::QWrite for Disabled {
|
impl xml::QWrite for Disabled {
|
||||||
|
|
|
@ -7,12 +7,11 @@ use super::error;
|
||||||
|
|
||||||
/// It's how we implement a DAV extension
|
/// It's how we implement a DAV extension
|
||||||
/// (That's the dark magic part...)
|
/// (That's the dark magic part...)
|
||||||
pub trait Node<T> = xml::QRead<T> + xml::QWrite + Debug + PartialEq;
|
pub trait Extension: std::fmt::Debug + PartialEq {
|
||||||
pub trait Extension {
|
type Error: xml::Node<Self::Error>;
|
||||||
type Error: Node<Self::Error>;
|
type Property: xml::Node<Self::Property>;
|
||||||
type Property: Node<Self::Property>;
|
type PropertyRequest: xml::Node<Self::PropertyRequest>;
|
||||||
type PropertyRequest: Node<Self::PropertyRequest>;
|
type ResourceType: xml::Node<Self::ResourceType>;
|
||||||
type ResourceType: Node<Self::ResourceType>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 14.1. activelock XML Element
|
/// 14.1. activelock XML Element
|
||||||
|
@ -333,7 +332,7 @@ pub enum LockType {
|
||||||
///
|
///
|
||||||
/// <!ELEMENT multistatus (response*, responsedescription?) >
|
/// <!ELEMENT multistatus (response*, responsedescription?) >
|
||||||
#[derive(Debug, PartialEq)]
|
#[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 responses: Vec<Response<E, N>>,
|
||||||
pub responsedescription: Option<ResponseDescription>,
|
pub responsedescription: Option<ResponseDescription>,
|
||||||
}
|
}
|
||||||
|
@ -465,7 +464,7 @@ pub enum PropFind<E: Extension> {
|
||||||
///
|
///
|
||||||
/// <!ELEMENT propstat (prop, status, error?, responsedescription?) >
|
/// <!ELEMENT propstat (prop, status, error?, responsedescription?) >
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct PropStat<E: Extension, N: Node<N>> {
|
pub struct PropStat<E: Extension, N: xml::Node<N>> {
|
||||||
pub prop: N,
|
pub prop: N,
|
||||||
pub status: Status,
|
pub status: Status,
|
||||||
pub error: Option<Error<E>>,
|
pub error: Option<Error<E>>,
|
||||||
|
@ -514,7 +513,7 @@ pub struct Remove<E: Extension>(pub PropName<E>);
|
||||||
/// --- rewritten as ---
|
/// --- rewritten as ---
|
||||||
/// <!ELEMENT response ((href+, status)|(href, propstat+), error?, responsedescription?, location?>
|
/// <!ELEMENT response ((href+, status)|(href, propstat+), error?, responsedescription?, location?>
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum StatusOrPropstat<E: Extension, N: Node<N>> {
|
pub enum StatusOrPropstat<E: Extension, N: xml::Node<N>> {
|
||||||
// One status, multiple hrefs...
|
// One status, multiple hrefs...
|
||||||
Status(Vec<Href>, Status),
|
Status(Vec<Href>, Status),
|
||||||
// A single href, multiple properties...
|
// A single href, multiple properties...
|
||||||
|
@ -522,7 +521,7 @@ pub enum StatusOrPropstat<E: Extension, N: Node<N>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[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 status_or_propstat: StatusOrPropstat<E, N>,
|
||||||
pub error: Option<Error<E>>,
|
pub error: Option<Error<E>>,
|
||||||
pub responsedescription: Option<ResponseDescription>,
|
pub responsedescription: Option<ResponseDescription>,
|
||||||
|
|
|
@ -19,9 +19,14 @@ pub trait QWrite {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), quick_xml::Error>;
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), quick_xml::Error>;
|
||||||
}
|
}
|
||||||
pub trait QRead<T> {
|
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
|
/// Transform a Rust object into an XML stream of characters
|
||||||
pub struct Writer<T: IWrite> {
|
pub struct Writer<T: IWrite> {
|
||||||
pub q: quick_xml::writer::Writer<T>,
|
pub q: quick_xml::writer::Writer<T>,
|
||||||
|
@ -106,6 +111,8 @@ impl<T: IRead> Reader<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disabled
|
||||||
/// maybe find start tag
|
/// maybe find start tag
|
||||||
pub async fn maybe_tag_start(&mut self, ns: &[u8], key: &str) -> Result<Option<Event<'static>>, ParsingError> {
|
pub async fn maybe_tag_start(&mut self, ns: &[u8], key: &str) -> Result<Option<Event<'static>>, ParsingError> {
|
||||||
println!("maybe start tag {}", key);
|
println!("maybe start tag {}", key);
|
||||||
|
@ -118,7 +125,6 @@ impl<T: IRead> Reader<T> {
|
||||||
|
|
||||||
/// find start tag
|
/// find start tag
|
||||||
pub async fn tag_start(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
|
pub async fn tag_start(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
|
||||||
println!("search start tag {}", key);
|
|
||||||
loop {
|
loop {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Event::Start(b) if self.is_tag(ns, key) => break,
|
Event::Start(b) if self.is_tag(ns, key) => break,
|
||||||
|
@ -127,6 +133,7 @@ impl<T: IRead> Reader<T> {
|
||||||
}
|
}
|
||||||
self.next().await
|
self.next().await
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// find stop tag
|
// find stop tag
|
||||||
pub async fn tag_stop(&mut self, ns: &[u8], key: &str) -> Result<Event<'static>, ParsingError> {
|
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