WIP lock/propertyupdate implementation
This commit is contained in:
parent
ba32a0d4a6
commit
05c952f020
4 changed files with 407 additions and 76 deletions
|
@ -12,6 +12,8 @@ use super::error::ParsingError;
|
||||||
use super::xml::{QRead, Reader, IRead, DAV_URN, CAL_URN};
|
use super::xml::{QRead, Reader, IRead, DAV_URN, CAL_URN};
|
||||||
|
|
||||||
// ---- ROOT ----
|
// ---- ROOT ----
|
||||||
|
|
||||||
|
/// Propfind request
|
||||||
impl<E: Extension> QRead<PropFind<E>> for PropFind<E> {
|
impl<E: Extension> QRead<PropFind<E>> for PropFind<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
// Find propfind
|
// Find propfind
|
||||||
|
@ -48,6 +50,37 @@ impl<E: Extension> QRead<PropFind<E>> for PropFind<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// PROPPATCH request
|
||||||
|
impl<E: Extension> QRead<PropertyUpdate<E>> for PropertyUpdate<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
xml.tag_start(DAV_URN, "propertyupdate").await?;
|
||||||
|
let mut collected_items = Vec::new();
|
||||||
|
loop {
|
||||||
|
// Try to collect a property item
|
||||||
|
if let Some(item) = PropertyUpdateItem::qread(xml).await? {
|
||||||
|
collected_items.push(item);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip or stop otherwise
|
||||||
|
match xml.peek() {
|
||||||
|
Event::End(_) => break,
|
||||||
|
_ => { xml.skip().await?; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.tag_stop(DAV_URN, "propertyupdate").await?;
|
||||||
|
Ok(Some(PropertyUpdate(collected_items)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//@TODO Multistatus
|
||||||
|
|
||||||
|
//@TODO LockInfo
|
||||||
|
|
||||||
|
//@TODO PropValue
|
||||||
|
|
||||||
|
/// Error response
|
||||||
impl<E: Extension> QRead<Error<E>> for Error<E> {
|
impl<E: Extension> QRead<Error<E>> for Error<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
xml.tag_start(DAV_URN, "error").await?;
|
xml.tag_start(DAV_URN, "error").await?;
|
||||||
|
@ -66,7 +99,56 @@ impl<E: Extension> QRead<Error<E>> for Error<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---- INNER XML
|
// ---- INNER XML
|
||||||
|
impl<E: Extension> QRead<PropertyUpdateItem<E>> for PropertyUpdateItem<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
if let Some(rm) = Remove::qread(xml).await? {
|
||||||
|
return Ok(Some(PropertyUpdateItem::Remove(rm)))
|
||||||
|
}
|
||||||
|
Ok(Set::qread(xml).await?.map(PropertyUpdateItem::Set))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Extension> QRead<Remove<E>> for Remove<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Start(b) if xml.is_tag(DAV_URN, "remove") => xml.next().await?,
|
||||||
|
_ => return Ok(None),
|
||||||
|
};
|
||||||
|
|
||||||
|
let propname = loop {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Start(b) | Event::Empty(b) if xml.is_tag(DAV_URN, "prop") => break PropName::qread(xml).await?,
|
||||||
|
_ => xml.skip().await?,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xml.tag_stop(DAV_URN, "remove").await?;
|
||||||
|
Ok(propname.map(Remove))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Extension> QRead<Set<E>> for Set<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Start(b) if xml.is_tag(DAV_URN, "set") => xml.next().await?,
|
||||||
|
_ => return Ok(None),
|
||||||
|
};
|
||||||
|
let propvalue = loop {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Start(b) | Event::Empty(b) if xml.is_tag(DAV_URN, "prop") => break PropValue::qread(xml).await?,
|
||||||
|
_ => xml.skip().await?,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
xml.tag_stop(DAV_URN, "set").await?;
|
||||||
|
Ok(propvalue.map(Set))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Extension> QRead<Violation<E>> for Violation<E> {
|
impl<E: Extension> QRead<Violation<E>> for Violation<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
loop {
|
loop {
|
||||||
|
@ -163,13 +245,17 @@ impl<E: Extension> QRead<Violation<E>> for Violation<E> {
|
||||||
impl<E: Extension> QRead<Include<E>> for Include<E> {
|
impl<E: Extension> QRead<Include<E>> for Include<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
xml.tag_start(DAV_URN, "include").await?;
|
xml.tag_start(DAV_URN, "include").await?;
|
||||||
let mut acc: Vec<PropertyRequest<E>> = Vec::new();
|
let mut acc = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
// Found a property
|
||||||
|
if let Some(prop) = PropertyRequest::qread(xml).await? {
|
||||||
|
acc.push(prop);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise skip or escape
|
||||||
match xml.peek() {
|
match xml.peek() {
|
||||||
Event::Start(_) | Event::Empty(_) => {
|
Event::End(_) => break,
|
||||||
PropertyRequest::qread(xml).await?.map(|v| acc.push(v));
|
|
||||||
},
|
|
||||||
Event::End(_) if xml.is_tag(DAV_URN, "include") => break,
|
|
||||||
_ => { xml.skip().await?; },
|
_ => { xml.skip().await?; },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,13 +267,17 @@ impl<E: Extension> QRead<Include<E>> for Include<E> {
|
||||||
impl<E: Extension> QRead<PropName<E>> for PropName<E> {
|
impl<E: Extension> QRead<PropName<E>> for PropName<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
xml.tag_start(DAV_URN, "prop").await?;
|
xml.tag_start(DAV_URN, "prop").await?;
|
||||||
let mut acc: Vec<PropertyRequest<E>> = Vec::new();
|
let mut acc = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
// Found a property
|
||||||
|
if let Some(prop) = PropertyRequest::qread(xml).await? {
|
||||||
|
acc.push(prop);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise skip or escape
|
||||||
match xml.peek() {
|
match xml.peek() {
|
||||||
Event::Start(_) | Event::Empty(_) => {
|
Event::End(_) => break,
|
||||||
PropertyRequest::qread(xml).await?.map(|v| acc.push(v));
|
|
||||||
},
|
|
||||||
Event::End(_) if xml.is_tag(DAV_URN, "prop") => break,
|
|
||||||
_ => { xml.skip().await?; },
|
_ => { xml.skip().await?; },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,18 +288,14 @@ impl<E: Extension> QRead<PropName<E>> for PropName<E> {
|
||||||
|
|
||||||
impl<E: Extension> QRead<PropertyRequest<E>> for PropertyRequest<E> {
|
impl<E: Extension> QRead<PropertyRequest<E>> for PropertyRequest<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
loop {
|
|
||||||
let bs = match xml.peek() {
|
let bs = match xml.peek() {
|
||||||
Event::Start(b) | Event::Empty(b) => b,
|
Event::Start(b) | Event::Empty(b) => b,
|
||||||
_ => {
|
_ => return Ok(None),
|
||||||
xml.skip().await?;
|
|
||||||
continue
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut maybe_res = None;
|
let mut maybe_res = None;
|
||||||
|
|
||||||
// Option 1: a pure DAV property
|
// Option 1: a pure core DAV property
|
||||||
let (ns, loc) = xml.rdr.resolve_element(bs.name());
|
let (ns, loc) = xml.rdr.resolve_element(bs.name());
|
||||||
if matches!(ns, Bound(Namespace(ns)) if ns == DAV_URN) {
|
if matches!(ns, Bound(Namespace(ns)) if ns == DAV_URN) {
|
||||||
maybe_res = match loc.into_inner() {
|
maybe_res = match loc.into_inner() {
|
||||||
|
@ -236,8 +322,236 @@ impl<E: Extension> QRead<PropertyRequest<E>> for PropertyRequest<E> {
|
||||||
maybe_res = E::PropertyRequest::qread(xml).await?.map(PropertyRequest::Extension);
|
maybe_res = E::PropertyRequest::qread(xml).await?.map(PropertyRequest::Extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(maybe_res)
|
Ok(maybe_res)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<E: Extension> QRead<PropValue<E>> for PropValue<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
xml.tag_start(DAV_URN, "prop").await?;
|
||||||
|
let mut acc = Vec::new();
|
||||||
|
loop {
|
||||||
|
// Found a property
|
||||||
|
if let Some(prop) = Property::qread(xml).await? {
|
||||||
|
acc.push(prop);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise skip or escape
|
||||||
|
match xml.peek() {
|
||||||
|
Event::End(_) => break,
|
||||||
|
_ => { xml.skip().await?; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xml.tag_stop(DAV_URN, "prop").await?;
|
||||||
|
Ok(Some(PropValue(acc)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Extension> QRead<Property<E>> for Property<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
use chrono::{DateTime, FixedOffset, TimeZone};
|
||||||
|
|
||||||
|
let bs = match xml.peek() {
|
||||||
|
Event::Start(b) | Event::Empty(b) => b,
|
||||||
|
_ => return Ok(None),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut maybe_res = None;
|
||||||
|
|
||||||
|
// Option 1: a pure core DAV property
|
||||||
|
let (ns, loc) = xml.rdr.resolve_element(bs.name());
|
||||||
|
if matches!(ns, Bound(Namespace(ns)) if ns == DAV_URN) {
|
||||||
|
maybe_res = match loc.into_inner() {
|
||||||
|
b"creationdate" => {
|
||||||
|
xml.next().await?;
|
||||||
|
let datestr = xml.tag_string().await?;
|
||||||
|
Some(Property::CreationDate(DateTime::parse_from_rfc3339(datestr.as_str())?))
|
||||||
|
},
|
||||||
|
b"displayname" => {
|
||||||
|
xml.next().await?;
|
||||||
|
Some(Property::DisplayName(xml.tag_string().await?))
|
||||||
|
},
|
||||||
|
b"getcontentlanguage" => {
|
||||||
|
xml.next().await?;
|
||||||
|
Some(Property::GetContentLanguage(xml.tag_string().await?))
|
||||||
|
},
|
||||||
|
b"getcontentlength" => {
|
||||||
|
xml.next().await?;
|
||||||
|
let cl = xml.tag_string().await?.parse::<u64>()?;
|
||||||
|
Some(Property::GetContentLength(cl))
|
||||||
|
},
|
||||||
|
b"getcontenttype" => {
|
||||||
|
xml.next().await?;
|
||||||
|
Some(Property::GetContentType(xml.tag_string().await?))
|
||||||
|
},
|
||||||
|
b"getetag" => {
|
||||||
|
xml.next().await?;
|
||||||
|
Some(Property::GetEtag(xml.tag_string().await?))
|
||||||
|
},
|
||||||
|
b"getlastmodified" => {
|
||||||
|
xml.next().await?;
|
||||||
|
xml.next().await?;
|
||||||
|
let datestr = xml.tag_string().await?;
|
||||||
|
Some(Property::CreationDate(DateTime::parse_from_rfc2822(datestr.as_str())?))
|
||||||
|
},
|
||||||
|
b"lockdiscovery" => {
|
||||||
|
// start tag
|
||||||
|
xml.next().await?;
|
||||||
|
|
||||||
|
let mut acc = Vec::new();
|
||||||
|
loop {
|
||||||
|
// If we find a lock
|
||||||
|
if let Some(lock) = ActiveLock::qread(xml).await? {
|
||||||
|
acc.push(lock);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise
|
||||||
|
match xml.peek() {
|
||||||
|
Event::End(_) => break,
|
||||||
|
_ => { xml.skip().await?; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xml.tag_stop(DAV_URN, "lockdiscovery").await?;
|
||||||
|
Some(Property::LockDiscovery(acc))
|
||||||
|
},
|
||||||
|
b"resourcetype" => {
|
||||||
|
xml.next().await?;
|
||||||
|
|
||||||
|
let mut acc = Vec::new();
|
||||||
|
loop {
|
||||||
|
// If we find a resource type...
|
||||||
|
if let Some(restype) = ResourceType::qread(xml).await? {
|
||||||
|
acc.push(restype);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise
|
||||||
|
match xml.peek() {
|
||||||
|
Event::End(_) => break,
|
||||||
|
_ => { xml.skip().await?; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xml.tag_stop(DAV_URN, "resourcetype").await?;
|
||||||
|
Some(Property::ResourceType(acc))
|
||||||
|
},
|
||||||
|
b"supportedlock" => {
|
||||||
|
xml.next().await?;
|
||||||
|
|
||||||
|
let mut acc = Vec::new();
|
||||||
|
loop {
|
||||||
|
// If we find a resource type...
|
||||||
|
if let Some(restype) = LockEntry::qread(xml).await? {
|
||||||
|
acc.push(restype);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise
|
||||||
|
match xml.peek() {
|
||||||
|
Event::End(_) => break,
|
||||||
|
_ => { xml.skip().await?; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xml.tag_stop(DAV_URN, "supportedlock").await?;
|
||||||
|
Some(Property::SupportedLock(acc))
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option 2: an extension property, delegating
|
||||||
|
if maybe_res.is_none() {
|
||||||
|
maybe_res = E::Property::qread(xml).await?.map(Property::Extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(maybe_res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QRead<ActiveLock> for ActiveLock {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Extension> QRead<ResourceType<E>> for ResourceType<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Empty(b) if xml.is_tag(DAV_URN, "collection") => {
|
||||||
|
xml.next().await?;
|
||||||
|
Ok(Some(ResourceType::Collection))
|
||||||
|
},
|
||||||
|
_ => Ok(E::ResourceType::qread(xml).await?.map(ResourceType::Extension)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QRead<LockEntry> for LockEntry {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
xml.tag_start(DAV_URN, "lockentry").await?;
|
||||||
|
let (mut maybe_scope, mut maybe_type) = (None, None);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Start(b) if xml.is_tag(DAV_URN, "lockscope") => {
|
||||||
|
maybe_scope = LockScope::qread(xml).await?;
|
||||||
|
},
|
||||||
|
Event::Start(b) if xml.is_tag(DAV_URN, "lockentry") => {
|
||||||
|
maybe_type = LockType::qread(xml).await?;
|
||||||
|
}
|
||||||
|
Event::End(_) => break,
|
||||||
|
_ => { xml.skip().await?; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let lockentry = match (maybe_scope, maybe_type) {
|
||||||
|
(Some(lockscope), Some(locktype)) => LockEntry { lockscope, locktype },
|
||||||
|
_ => return Err(ParsingError::MissingChild),
|
||||||
|
};
|
||||||
|
|
||||||
|
xml.tag_stop(DAV_URN, "lockentry").await?;
|
||||||
|
Ok(Some(lockentry))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QRead<LockScope> for LockScope {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
xml.tag_start(DAV_URN, "lockscope").await?;
|
||||||
|
let lockscope = loop {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Empty(b) if xml.is_tag(DAV_URN, "exclusive") => {
|
||||||
|
xml.next().await?;
|
||||||
|
break LockScope::Exclusive
|
||||||
|
},
|
||||||
|
Event::Empty(b) if xml.is_tag(DAV_URN, "shared") => {
|
||||||
|
xml.next().await?;
|
||||||
|
break LockScope::Shared
|
||||||
|
}
|
||||||
|
_ => xml.skip().await?,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xml.tag_stop(DAV_URN, "lockscope").await?;
|
||||||
|
Ok(Some(lockscope))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QRead<LockType> for LockType {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
|
xml.tag_start(DAV_URN, "locktype").await?;
|
||||||
|
let locktype = loop {
|
||||||
|
match xml.peek() {
|
||||||
|
Event::Empty(b) if xml.is_tag(DAV_URN, "write") => {
|
||||||
|
xml.next().await?;
|
||||||
|
break LockType::Write
|
||||||
|
}
|
||||||
|
_ => xml.skip().await?,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
xml.tag_stop(DAV_URN, "locktype").await?;
|
||||||
|
Ok(Some(locktype))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,22 +562,7 @@ impl QRead<Href> for Href {
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut url = String::new();
|
let mut url = xml.tag_string().await?;
|
||||||
loop {
|
|
||||||
match xml.peek() {
|
|
||||||
Event::End(_) => break,
|
|
||||||
Event::Start(_) | Event::Empty(_) => return Err(ParsingError::WrongToken),
|
|
||||||
Event::CData(unescaped) => {
|
|
||||||
url.push_str(std::str::from_utf8(unescaped.as_ref())?);
|
|
||||||
xml.next().await?
|
|
||||||
},
|
|
||||||
Event::Text(escaped) => {
|
|
||||||
url.push_str(escaped.unescape()?.as_ref());
|
|
||||||
xml.next().await?
|
|
||||||
}
|
|
||||||
_ => xml.skip().await?,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
xml.tag_stop(DAV_URN, "href").await?;
|
xml.tag_stop(DAV_URN, "href").await?;
|
||||||
Ok(Some(Href(url)))
|
Ok(Some(Href(url)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,20 @@ impl<E: Extension> QWrite for PropValue<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Error response
|
||||||
|
impl<E: Extension> QWrite for Error<E> {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
let start = xml.create_dav_element("error");
|
||||||
|
let end = start.to_end();
|
||||||
|
|
||||||
|
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
||||||
|
for violation in &self.0 {
|
||||||
|
violation.qwrite(xml).await?;
|
||||||
|
}
|
||||||
|
xml.q.write_event_async(Event::End(end)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- XML inner elements
|
// --- XML inner elements
|
||||||
impl<E: Extension> QWrite for PropertyUpdateItem<E> {
|
impl<E: Extension> QWrite for PropertyUpdateItem<E> {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
@ -584,19 +598,6 @@ impl QWrite for LockEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Extension> QWrite for Error<E> {
|
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
|
||||||
let start = xml.create_dav_element("error");
|
|
||||||
let end = start.to_end();
|
|
||||||
|
|
||||||
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
|
||||||
for violation in &self.0 {
|
|
||||||
violation.qwrite(xml).await?;
|
|
||||||
}
|
|
||||||
xml.q.write_event_async(Event::End(end)).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Extension> QWrite for Violation<E> {
|
impl<E: Extension> QWrite for Violation<E> {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
let mut atom = async |c| {
|
let mut atom = async |c| {
|
||||||
|
|
|
@ -8,6 +8,8 @@ pub enum ParsingError {
|
||||||
TagNotFound,
|
TagNotFound,
|
||||||
Utf8Error(std::str::Utf8Error),
|
Utf8Error(std::str::Utf8Error),
|
||||||
QuickXml(quick_xml::Error),
|
QuickXml(quick_xml::Error),
|
||||||
|
Chrono(chrono::format::ParseError),
|
||||||
|
Int(std::num::ParseIntError),
|
||||||
Eof
|
Eof
|
||||||
}
|
}
|
||||||
impl From<AttrError> for ParsingError {
|
impl From<AttrError> for ParsingError {
|
||||||
|
@ -25,3 +27,14 @@ impl From<std::str::Utf8Error> for ParsingError {
|
||||||
Self::Utf8Error(value)
|
Self::Utf8Error(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl From<chrono::format::ParseError> for ParsingError {
|
||||||
|
fn from(value: chrono::format::ParseError) -> Self {
|
||||||
|
Self::Chrono(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::num::ParseIntError> for ParsingError {
|
||||||
|
fn from(value: std::num::ParseIntError) -> Self {
|
||||||
|
Self::Int(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -129,5 +129,23 @@ impl<T: IRead> Reader<T> {
|
||||||
}
|
}
|
||||||
self.next().await
|
self.next().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn tag_string(&mut self) -> Result<String, ParsingError> {
|
||||||
|
let mut acc = String::new();
|
||||||
|
loop {
|
||||||
|
match self.peek() {
|
||||||
|
Event::CData(unescaped) => {
|
||||||
|
acc.push_str(std::str::from_utf8(unescaped.as_ref())?);
|
||||||
|
self.next().await?
|
||||||
|
},
|
||||||
|
Event::Text(escaped) => {
|
||||||
|
acc.push_str(escaped.unescape()?.as_ref());
|
||||||
|
self.next().await?
|
||||||
|
}
|
||||||
|
Event::End(_) | Event::Start(_) | Event::Empty(_) => return Ok(acc),
|
||||||
|
_ => self.next().await?,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue