parse property for sync + versioning
This commit is contained in:
parent
5b1da2a33b
commit
1c9d2eab69
13 changed files with 414 additions and 15 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -70,6 +70,7 @@ dependencies = [
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -12,3 +12,4 @@ http.workspace = true
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
|
tracing.workspace = true
|
||||||
|
|
|
@ -104,6 +104,28 @@ impl QRead<FreeBusyQuery> for FreeBusyQuery {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl QRead<ReportTypeName> for ReportTypeName {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
if xml.maybe_open(DAV_URN, "calendar-query").await?.is_some() {
|
||||||
|
xml.close().await?;
|
||||||
|
return Ok(Self::Query);
|
||||||
|
}
|
||||||
|
if xml
|
||||||
|
.maybe_open(DAV_URN, "calendar-multiget")
|
||||||
|
.await?
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
xml.close().await?;
|
||||||
|
return Ok(Self::Multiget);
|
||||||
|
}
|
||||||
|
if xml.maybe_open(DAV_URN, "free-busy-query").await?.is_some() {
|
||||||
|
xml.close().await?;
|
||||||
|
return Ok(Self::FreeBusy);
|
||||||
|
}
|
||||||
|
Err(ParsingError::Recoverable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---- EXTENSIONS ---
|
// ---- EXTENSIONS ---
|
||||||
impl QRead<Violation> for Violation {
|
impl QRead<Violation> for Violation {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
|
|
@ -33,6 +33,25 @@ impl<E: Extension> QWrite for MkCalendarResponse<E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------- REPORT METHOD -------------------------------------
|
// ----------------------- REPORT METHOD -------------------------------------
|
||||||
|
impl QWrite for ReportTypeName {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
match self {
|
||||||
|
Self::Query => {
|
||||||
|
let start = xml.create_dav_element("calendar-query");
|
||||||
|
xml.q.write_event_async(Event::Empty(start)).await
|
||||||
|
}
|
||||||
|
Self::Multiget => {
|
||||||
|
let start = xml.create_dav_element("calendar-multiget");
|
||||||
|
xml.q.write_event_async(Event::Empty(start)).await
|
||||||
|
}
|
||||||
|
Self::FreeBusy => {
|
||||||
|
let start = xml.create_dav_element("free-busy-query");
|
||||||
|
xml.q.write_event_async(Event::Empty(start)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Extension> QWrite for ReportType<E> {
|
impl<E: Extension> QWrite for ReportType<E> {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -50,6 +50,13 @@ pub struct MkCalendar<E: dav::Extension>(pub dav::Set<E>);
|
||||||
pub struct MkCalendarResponse<E: dav::Extension>(pub Vec<dav::PropStat<E>>);
|
pub struct MkCalendarResponse<E: dav::Extension>(pub Vec<dav::PropStat<E>>);
|
||||||
|
|
||||||
// --- (REPORT PART) ---
|
// --- (REPORT PART) ---
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum ReportTypeName {
|
||||||
|
Query,
|
||||||
|
Multiget,
|
||||||
|
FreeBusy,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum ReportType<E: dav::Extension> {
|
pub enum ReportType<E: dav::Extension> {
|
||||||
Query(CalendarQuery<E>),
|
Query(CalendarQuery<E>),
|
||||||
|
|
|
@ -3,6 +3,7 @@ use super::caltypes as cal;
|
||||||
use super::error;
|
use super::error;
|
||||||
use super::synctypes as sync;
|
use super::synctypes as sync;
|
||||||
use super::types as dav;
|
use super::types as dav;
|
||||||
|
use super::versioningtypes as vers;
|
||||||
use super::xml;
|
use super::xml;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -33,6 +34,7 @@ impl dav::Extension for Core {
|
||||||
type PropertyRequest = Disabled;
|
type PropertyRequest = Disabled;
|
||||||
type ResourceType = Disabled;
|
type ResourceType = Disabled;
|
||||||
type ReportType = Disabled;
|
type ReportType = Disabled;
|
||||||
|
type ReportTypeName = Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebDAV with the base Calendar implementation (RFC4791)
|
// WebDAV with the base Calendar implementation (RFC4791)
|
||||||
|
@ -44,6 +46,7 @@ impl dav::Extension for Calendar {
|
||||||
type PropertyRequest = cal::PropertyRequest;
|
type PropertyRequest = cal::PropertyRequest;
|
||||||
type ResourceType = cal::ResourceType;
|
type ResourceType = cal::ResourceType;
|
||||||
type ReportType = cal::ReportType<Calendar>;
|
type ReportType = cal::ReportType<Calendar>;
|
||||||
|
type ReportTypeName = cal::ReportTypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACL
|
// ACL
|
||||||
|
@ -55,6 +58,7 @@ impl dav::Extension for Acl {
|
||||||
type PropertyRequest = acl::PropertyRequest;
|
type PropertyRequest = acl::PropertyRequest;
|
||||||
type ResourceType = acl::ResourceType;
|
type ResourceType = acl::ResourceType;
|
||||||
type ReportType = Disabled;
|
type ReportType = Disabled;
|
||||||
|
type ReportTypeName = Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All merged
|
// All merged
|
||||||
|
@ -62,27 +66,38 @@ impl dav::Extension for Acl {
|
||||||
pub struct All {}
|
pub struct All {}
|
||||||
impl dav::Extension for All {
|
impl dav::Extension for All {
|
||||||
type Error = cal::Violation;
|
type Error = cal::Violation;
|
||||||
type Property = Property;
|
type Property = Property<All>;
|
||||||
type PropertyRequest = PropertyRequest;
|
type PropertyRequest = PropertyRequest;
|
||||||
type ResourceType = ResourceType;
|
type ResourceType = ResourceType;
|
||||||
type ReportType = ReportType<All>;
|
type ReportType = ReportType<All>;
|
||||||
|
type ReportTypeName = ReportTypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Property {
|
pub enum Property<E: dav::Extension> {
|
||||||
Cal(cal::Property),
|
Cal(cal::Property),
|
||||||
Acl(acl::Property),
|
Acl(acl::Property),
|
||||||
|
Sync(sync::Property),
|
||||||
|
Vers(vers::Property<E>),
|
||||||
}
|
}
|
||||||
impl xml::QRead<Property> for Property {
|
impl<E: dav::Extension> xml::QRead<Property<E>> for Property<E> {
|
||||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||||
match cal::Property::qread(xml).await {
|
match cal::Property::qread(xml).await {
|
||||||
Err(error::ParsingError::Recoverable) => (),
|
Err(error::ParsingError::Recoverable) => (),
|
||||||
otherwise => return otherwise.map(Property::Cal),
|
otherwise => return otherwise.map(Property::<E>::Cal),
|
||||||
}
|
}
|
||||||
acl::Property::qread(xml).await.map(Property::Acl)
|
match acl::Property::qread(xml).await {
|
||||||
|
Err(error::ParsingError::Recoverable) => (),
|
||||||
|
otherwise => return otherwise.map(Property::Acl),
|
||||||
|
}
|
||||||
|
match sync::Property::qread(xml).await {
|
||||||
|
Err(error::ParsingError::Recoverable) => (),
|
||||||
|
otherwise => return otherwise.map(Property::Sync),
|
||||||
|
}
|
||||||
|
vers::Property::qread(xml).await.map(Property::Vers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl xml::QWrite for Property {
|
impl<E: dav::Extension> xml::QWrite for Property<E> {
|
||||||
async fn qwrite(
|
async fn qwrite(
|
||||||
&self,
|
&self,
|
||||||
xml: &mut xml::Writer<impl xml::IWrite>,
|
xml: &mut xml::Writer<impl xml::IWrite>,
|
||||||
|
@ -90,6 +105,8 @@ impl xml::QWrite for Property {
|
||||||
match self {
|
match self {
|
||||||
Self::Cal(c) => c.qwrite(xml).await,
|
Self::Cal(c) => c.qwrite(xml).await,
|
||||||
Self::Acl(a) => a.qwrite(xml).await,
|
Self::Acl(a) => a.qwrite(xml).await,
|
||||||
|
Self::Sync(s) => s.qwrite(xml).await,
|
||||||
|
Self::Vers(v) => v.qwrite(xml).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +115,8 @@ impl xml::QWrite for Property {
|
||||||
pub enum PropertyRequest {
|
pub enum PropertyRequest {
|
||||||
Cal(cal::PropertyRequest),
|
Cal(cal::PropertyRequest),
|
||||||
Acl(acl::PropertyRequest),
|
Acl(acl::PropertyRequest),
|
||||||
|
Sync(sync::PropertyRequest),
|
||||||
|
Vers(vers::PropertyRequest),
|
||||||
}
|
}
|
||||||
impl xml::QRead<PropertyRequest> for PropertyRequest {
|
impl xml::QRead<PropertyRequest> for PropertyRequest {
|
||||||
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||||
|
@ -105,9 +124,17 @@ impl xml::QRead<PropertyRequest> for PropertyRequest {
|
||||||
Err(error::ParsingError::Recoverable) => (),
|
Err(error::ParsingError::Recoverable) => (),
|
||||||
otherwise => return otherwise.map(PropertyRequest::Cal),
|
otherwise => return otherwise.map(PropertyRequest::Cal),
|
||||||
}
|
}
|
||||||
acl::PropertyRequest::qread(xml)
|
match acl::PropertyRequest::qread(xml).await {
|
||||||
|
Err(error::ParsingError::Recoverable) => (),
|
||||||
|
otherwise => return otherwise.map(PropertyRequest::Acl),
|
||||||
|
}
|
||||||
|
match sync::PropertyRequest::qread(xml).await {
|
||||||
|
Err(error::ParsingError::Recoverable) => (),
|
||||||
|
otherwise => return otherwise.map(PropertyRequest::Sync),
|
||||||
|
}
|
||||||
|
vers::PropertyRequest::qread(xml)
|
||||||
.await
|
.await
|
||||||
.map(PropertyRequest::Acl)
|
.map(PropertyRequest::Vers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl xml::QWrite for PropertyRequest {
|
impl xml::QWrite for PropertyRequest {
|
||||||
|
@ -118,6 +145,8 @@ impl xml::QWrite for PropertyRequest {
|
||||||
match self {
|
match self {
|
||||||
Self::Cal(c) => c.qwrite(xml).await,
|
Self::Cal(c) => c.qwrite(xml).await,
|
||||||
Self::Acl(a) => a.qwrite(xml).await,
|
Self::Acl(a) => a.qwrite(xml).await,
|
||||||
|
Self::Sync(s) => s.qwrite(xml).await,
|
||||||
|
Self::Vers(v) => v.qwrite(xml).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,3 +204,31 @@ impl<E: dav::Extension> xml::QWrite for ReportType<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum ReportTypeName {
|
||||||
|
Cal(cal::ReportTypeName),
|
||||||
|
Sync(sync::ReportTypeName),
|
||||||
|
}
|
||||||
|
impl xml::QRead<ReportTypeName> for ReportTypeName {
|
||||||
|
async fn qread(xml: &mut xml::Reader<impl xml::IRead>) -> Result<Self, error::ParsingError> {
|
||||||
|
match cal::ReportTypeName::qread(xml).await {
|
||||||
|
Err(error::ParsingError::Recoverable) => (),
|
||||||
|
otherwise => return otherwise.map(ReportTypeName::Cal),
|
||||||
|
}
|
||||||
|
sync::ReportTypeName::qread(xml)
|
||||||
|
.await
|
||||||
|
.map(ReportTypeName::Sync)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl xml::QWrite for ReportTypeName {
|
||||||
|
async fn qwrite(
|
||||||
|
&self,
|
||||||
|
xml: &mut xml::Writer<impl xml::IWrite>,
|
||||||
|
) -> Result<(), quick_xml::Error> {
|
||||||
|
match self {
|
||||||
|
Self::Cal(c) => c.qwrite(xml).await,
|
||||||
|
Self::Sync(s) => s.qwrite(xml).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,34 @@ use super::synctypes::*;
|
||||||
use super::types as dav;
|
use super::types as dav;
|
||||||
use super::xml::{IRead, QRead, Reader, DAV_URN};
|
use super::xml::{IRead, QRead, Reader, DAV_URN};
|
||||||
|
|
||||||
|
impl QRead<PropertyRequest> for PropertyRequest {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
let mut dirty = false;
|
||||||
|
let mut m_cdr = None;
|
||||||
|
xml.maybe_read(&mut m_cdr, &mut dirty).await?;
|
||||||
|
m_cdr.ok_or(ParsingError::Recoverable).map(Self::SyncToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QRead<Property> for Property {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
let mut dirty = false;
|
||||||
|
let mut m_cdr = None;
|
||||||
|
xml.maybe_read(&mut m_cdr, &mut dirty).await?;
|
||||||
|
m_cdr.ok_or(ParsingError::Recoverable).map(Self::SyncToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QRead<ReportTypeName> for ReportTypeName {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
if xml.maybe_open(DAV_URN, "sync-collection").await?.is_some() {
|
||||||
|
xml.close().await?;
|
||||||
|
return Ok(Self::SyncCollection);
|
||||||
|
}
|
||||||
|
Err(ParsingError::Recoverable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: dav::Extension> QRead<SyncCollection<E>> for SyncCollection<E> {
|
impl<E: dav::Extension> QRead<SyncCollection<E>> for SyncCollection<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
xml.open(DAV_URN, "sync-collection").await?;
|
xml.open(DAV_URN, "sync-collection").await?;
|
||||||
|
@ -75,7 +103,7 @@ impl QRead<SyncLevel> for SyncLevel {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::realization::All;
|
use crate::realization::{self, All};
|
||||||
use crate::types as dav;
|
use crate::types as dav;
|
||||||
use crate::versioningtypes as vers;
|
use crate::versioningtypes as vers;
|
||||||
use crate::xml::Node;
|
use crate::xml::Node;
|
||||||
|
@ -172,4 +200,42 @@ mod tests {
|
||||||
assert_eq!(got, expected);
|
assert_eq!(got, expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn prop_req() {
|
||||||
|
let expected = dav::PropName::<All>(vec![dav::PropertyRequest::Extension(
|
||||||
|
realization::PropertyRequest::Sync(PropertyRequest::SyncToken(
|
||||||
|
SyncTokenRequest::InitialSync,
|
||||||
|
)),
|
||||||
|
)]);
|
||||||
|
let src = r#"<prop xmlns="DAV:"><sync-token/></prop>"#;
|
||||||
|
let got = deserialize::<dav::PropName<All>>(src).await;
|
||||||
|
assert_eq!(got, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn prop_val() {
|
||||||
|
let expected = dav::PropValue::<All>(vec![
|
||||||
|
dav::Property::Extension(realization::Property::Sync(Property::SyncToken(SyncToken(
|
||||||
|
"http://example.com/ns/sync/1232".into(),
|
||||||
|
)))),
|
||||||
|
dav::Property::Extension(realization::Property::Vers(
|
||||||
|
vers::Property::SupportedReportSet(vec![vers::SupportedReport(
|
||||||
|
vers::ReportName::Extension(realization::ReportTypeName::Sync(
|
||||||
|
ReportTypeName::SyncCollection,
|
||||||
|
)),
|
||||||
|
)]),
|
||||||
|
)),
|
||||||
|
]);
|
||||||
|
let src = r#"<prop xmlns="DAV:">
|
||||||
|
<sync-token>http://example.com/ns/sync/1232</sync-token>
|
||||||
|
<supported-report-set>
|
||||||
|
<supported-report>
|
||||||
|
<report><sync-collection/></report>
|
||||||
|
</supported-report>
|
||||||
|
</supported-report-set>
|
||||||
|
</prop>"#;
|
||||||
|
let got = deserialize::<dav::PropValue<All>>(src).await;
|
||||||
|
assert_eq!(got, expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,33 @@ use super::synctypes::*;
|
||||||
use super::types::Extension;
|
use super::types::Extension;
|
||||||
use super::xml::{IWrite, QWrite, Writer};
|
use super::xml::{IWrite, QWrite, Writer};
|
||||||
|
|
||||||
|
impl QWrite for Property {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
match self {
|
||||||
|
Self::SyncToken(token) => token.qwrite(xml).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QWrite for PropertyRequest {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
match self {
|
||||||
|
Self::SyncToken(token) => token.qwrite(xml).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QWrite for ReportTypeName {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
match self {
|
||||||
|
Self::SyncCollection => {
|
||||||
|
let start = xml.create_dav_element("sync-collection");
|
||||||
|
xml.q.write_event_async(Event::Empty(start)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Extension> QWrite for SyncCollection<E> {
|
impl<E: Extension> QWrite for SyncCollection<E> {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
let start = xml.create_dav_element("sync-collection");
|
let start = xml.create_dav_element("sync-collection");
|
||||||
|
@ -72,7 +99,7 @@ impl QWrite for SyncLevel {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::realization::All;
|
use crate::realization::{self, All};
|
||||||
use crate::types as dav;
|
use crate::types as dav;
|
||||||
use crate::versioningtypes as vers;
|
use crate::versioningtypes as vers;
|
||||||
use crate::xml::Node;
|
use crate::xml::Node;
|
||||||
|
@ -92,6 +119,7 @@ mod tests {
|
||||||
src.qwrite(&mut writer).await.expect("xml serialization");
|
src.qwrite(&mut writer).await.expect("xml serialization");
|
||||||
tokio_buffer.flush().await.expect("tokio buffer flush");
|
tokio_buffer.flush().await.expect("tokio buffer flush");
|
||||||
let got = std::str::from_utf8(buffer.as_slice()).unwrap();
|
let got = std::str::from_utf8(buffer.as_slice()).unwrap();
|
||||||
|
println!("{:?}", got);
|
||||||
|
|
||||||
// deserialize
|
// deserialize
|
||||||
let mut rdr = Reader::new(quick_xml::NsReader::from_reader(got.as_bytes()))
|
let mut rdr = Reader::new(quick_xml::NsReader::from_reader(got.as_bytes()))
|
||||||
|
@ -141,4 +169,31 @@ mod tests {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn prop_req() {
|
||||||
|
serialize_deserialize(&dav::PropName::<All>(vec![
|
||||||
|
dav::PropertyRequest::Extension(realization::PropertyRequest::Sync(
|
||||||
|
PropertyRequest::SyncToken(SyncTokenRequest::InitialSync),
|
||||||
|
)),
|
||||||
|
]))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn prop_val() {
|
||||||
|
serialize_deserialize(&dav::PropValue::<All>(vec![
|
||||||
|
dav::Property::Extension(realization::Property::Sync(Property::SyncToken(SyncToken(
|
||||||
|
"http://example.com/ns/sync/1232".into(),
|
||||||
|
)))),
|
||||||
|
dav::Property::Extension(realization::Property::Vers(
|
||||||
|
vers::Property::SupportedReportSet(vec![vers::SupportedReport(
|
||||||
|
vers::ReportName::Extension(realization::ReportTypeName::Sync(
|
||||||
|
ReportTypeName::SyncCollection,
|
||||||
|
)),
|
||||||
|
)]),
|
||||||
|
)),
|
||||||
|
]))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,21 @@ use super::versioningtypes as vers;
|
||||||
// RFC 6578
|
// RFC 6578
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6578
|
// https://datatracker.ietf.org/doc/html/rfc6578
|
||||||
|
|
||||||
//@FIXME add SyncTokenRequest to PropertyRequest
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
//@FIXME add SyncToken to Property
|
pub enum PropertyRequest {
|
||||||
|
SyncToken(SyncTokenRequest),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum Property {
|
||||||
|
SyncToken(SyncToken),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum ReportTypeName {
|
||||||
|
SyncCollection,
|
||||||
|
}
|
||||||
|
|
||||||
//@FIXME add SyncToken to Multistatus
|
//@FIXME add SyncToken to Multistatus
|
||||||
|
|
||||||
/// Name: sync-collection
|
/// Name: sync-collection
|
||||||
|
|
|
@ -12,6 +12,7 @@ pub trait Extension: std::fmt::Debug + PartialEq + Clone {
|
||||||
type PropertyRequest: xml::Node<Self::PropertyRequest>;
|
type PropertyRequest: xml::Node<Self::PropertyRequest>;
|
||||||
type ResourceType: xml::Node<Self::ResourceType>;
|
type ResourceType: xml::Node<Self::ResourceType>;
|
||||||
type ReportType: xml::Node<Self::ReportType>;
|
type ReportType: xml::Node<Self::ReportType>;
|
||||||
|
type ReportTypeName: xml::Node<Self::ReportTypeName>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 14.1. activelock XML Element
|
/// 14.1. activelock XML Element
|
||||||
|
|
|
@ -3,12 +3,87 @@ use super::types as dav;
|
||||||
use super::versioningtypes::*;
|
use super::versioningtypes::*;
|
||||||
use super::xml::{IRead, QRead, Reader, DAV_URN};
|
use super::xml::{IRead, QRead, Reader, DAV_URN};
|
||||||
|
|
||||||
|
// -- extensions ---
|
||||||
|
impl QRead<PropertyRequest> for PropertyRequest {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
if xml
|
||||||
|
.maybe_open(DAV_URN, "supported-report-set")
|
||||||
|
.await?
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
xml.close().await?;
|
||||||
|
return Ok(Self::SupportedReportSet);
|
||||||
|
}
|
||||||
|
return Err(ParsingError::Recoverable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: dav::Extension> QRead<Property<E>> for Property<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
if xml
|
||||||
|
.maybe_open(DAV_URN, "supported-report-set")
|
||||||
|
.await?
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
let supported_reports = xml.collect().await?;
|
||||||
|
xml.close().await?;
|
||||||
|
return Ok(Property::SupportedReportSet(supported_reports));
|
||||||
|
}
|
||||||
|
Err(ParsingError::Recoverable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: dav::Extension> QRead<SupportedReport<E>> for SupportedReport<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
xml.open(DAV_URN, "supported-report").await?;
|
||||||
|
let r = xml.find().await?;
|
||||||
|
xml.close().await?;
|
||||||
|
Ok(SupportedReport(r))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: dav::Extension> QRead<ReportName<E>> for ReportName<E> {
|
||||||
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
|
xml.open(DAV_URN, "report").await?;
|
||||||
|
|
||||||
|
let final_result = if xml.maybe_open(DAV_URN, "version-tree").await?.is_some() {
|
||||||
|
xml.close().await?;
|
||||||
|
Ok(ReportName::VersionTree)
|
||||||
|
} else if xml.maybe_open(DAV_URN, "expand-property").await?.is_some() {
|
||||||
|
xml.close().await?;
|
||||||
|
Ok(ReportName::ExpandProperty)
|
||||||
|
} else {
|
||||||
|
let x = match xml.maybe_find().await? {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return Err(ParsingError::MissingChild),
|
||||||
|
};
|
||||||
|
Ok(ReportName::Extension(x))
|
||||||
|
//E::ReportTypeName::qread(xml).await.map(ReportName::Extension)
|
||||||
|
};
|
||||||
|
|
||||||
|
xml.close().await?;
|
||||||
|
final_result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: dav::Extension> QRead<Report<E>> for Report<E> {
|
impl<E: dav::Extension> QRead<Report<E>> for Report<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
|
||||||
//@FIXME VersionTree not implemented
|
xml.open(DAV_URN, "report").await?;
|
||||||
//@FIXME ExpandTree not implemented
|
|
||||||
|
|
||||||
|
let final_result = if xml.maybe_open(DAV_URN, "version-tree").await?.is_some() {
|
||||||
|
xml.close().await?;
|
||||||
|
tracing::warn!("version-tree is not implemented, skipping");
|
||||||
|
Ok(Report::VersionTree)
|
||||||
|
} else if xml.maybe_open(DAV_URN, "expand-property").await?.is_some() {
|
||||||
|
xml.close().await?;
|
||||||
|
tracing::warn!("expand-property is not implemented, skipping");
|
||||||
|
Ok(Report::ExpandProperty)
|
||||||
|
} else {
|
||||||
E::ReportType::qread(xml).await.map(Report::Extension)
|
E::ReportType::qread(xml).await.map(Report::Extension)
|
||||||
|
};
|
||||||
|
|
||||||
|
xml.close().await?;
|
||||||
|
final_result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,67 @@ use super::types::Extension;
|
||||||
use super::versioningtypes::*;
|
use super::versioningtypes::*;
|
||||||
use super::xml::{IWrite, QWrite, Writer};
|
use super::xml::{IWrite, QWrite, Writer};
|
||||||
|
|
||||||
|
// --- extensions to PROP
|
||||||
|
impl QWrite for PropertyRequest {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
match self {
|
||||||
|
Self::SupportedReportSet => {
|
||||||
|
let start = xml.create_dav_element("supported-report-set");
|
||||||
|
xml.q.write_event_async(Event::Empty(start)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Extension> QWrite for Property<E> {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
match self {
|
||||||
|
Self::SupportedReportSet(set) => {
|
||||||
|
let start = xml.create_dav_element("supported-report-set");
|
||||||
|
let end = start.to_end();
|
||||||
|
|
||||||
|
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
||||||
|
for v in set.iter() {
|
||||||
|
v.qwrite(xml).await?;
|
||||||
|
}
|
||||||
|
xml.q.write_event_async(Event::End(end)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Extension> QWrite for SupportedReport<E> {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
let start = xml.create_dav_element("supported-report");
|
||||||
|
let end = start.to_end();
|
||||||
|
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
||||||
|
self.0.qwrite(xml).await?;
|
||||||
|
xml.q.write_event_async(Event::End(end)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Extension> QWrite for ReportName<E> {
|
||||||
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
|
let start = xml.create_dav_element("report");
|
||||||
|
let end = start.to_end();
|
||||||
|
|
||||||
|
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
||||||
|
match self {
|
||||||
|
Self::VersionTree => {
|
||||||
|
let start = xml.create_dav_element("version-tree");
|
||||||
|
xml.q.write_event_async(Event::Empty(start)).await?;
|
||||||
|
}
|
||||||
|
Self::ExpandProperty => {
|
||||||
|
let start = xml.create_dav_element("expand-property");
|
||||||
|
xml.q.write_event_async(Event::Empty(start)).await?;
|
||||||
|
}
|
||||||
|
Self::Extension(ext) => ext.qwrite(xml).await?,
|
||||||
|
};
|
||||||
|
xml.q.write_event_async(Event::End(end)).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- root REPORT object ---
|
||||||
impl<E: Extension> QWrite for Report<E> {
|
impl<E: Extension> QWrite for Report<E> {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -15,6 +76,7 @@ impl<E: Extension> QWrite for Report<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- limit REPORT parameter ---
|
||||||
impl QWrite for Limit {
|
impl QWrite for Limit {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
let start = xml.create_dav_element("limit");
|
let start = xml.create_dav_element("limit");
|
||||||
|
|
|
@ -21,6 +21,26 @@ use super::types as dav;
|
||||||
// <!ELEMENT report ANY>
|
// <!ELEMENT report ANY>
|
||||||
// ANY value: a report element type
|
// ANY value: a report element type
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum PropertyRequest {
|
||||||
|
SupportedReportSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum Property<E: dav::Extension> {
|
||||||
|
SupportedReportSet(Vec<SupportedReport<E>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub struct SupportedReport<E: dav::Extension>(pub ReportName<E>);
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum ReportName<E: dav::Extension> {
|
||||||
|
VersionTree,
|
||||||
|
ExpandProperty,
|
||||||
|
Extension(E::ReportTypeName),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Report<E: dav::Extension> {
|
pub enum Report<E: dav::Extension> {
|
||||||
VersionTree, // Not yet implemented
|
VersionTree, // Not yet implemented
|
||||||
|
|
Loading…
Reference in a new issue