aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2024-05-28 12:38:22 +0200
committerQuentin Dufour <quentin@deuxfleurs.fr>2024-05-28 12:38:22 +0200
commit1c9d2eab6976993c85eaa3e8eb4f1c433258fd16 (patch)
tree6e29fdc6a465295f2142163744e8851a1cb5e95a
parent5b1da2a33b265b674a130a90377c289faea7a210 (diff)
downloadaerogramme-1c9d2eab6976993c85eaa3e8eb4f1c433258fd16.tar.gz
aerogramme-1c9d2eab6976993c85eaa3e8eb4f1c433258fd16.zip
parse property for sync + versioning
-rw-r--r--Cargo.lock1
-rw-r--r--aero-dav/Cargo.toml1
-rw-r--r--aero-dav/src/caldecoder.rs22
-rw-r--r--aero-dav/src/calencoder.rs19
-rw-r--r--aero-dav/src/caltypes.rs7
-rw-r--r--aero-dav/src/realization.rs73
-rw-r--r--aero-dav/src/syncdecoder.rs68
-rw-r--r--aero-dav/src/syncencoder.rs57
-rw-r--r--aero-dav/src/synctypes.rs17
-rw-r--r--aero-dav/src/types.rs1
-rw-r--r--aero-dav/src/versioningdecoder.rs81
-rw-r--r--aero-dav/src/versioningencoder.rs62
-rw-r--r--aero-dav/src/versioningtypes.rs20
13 files changed, 414 insertions, 15 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d22a5fc..0a159ae 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -70,6 +70,7 @@ dependencies = [
"http 1.1.0",
"quick-xml",
"tokio",
+ "tracing",
]
[[package]]
diff --git a/aero-dav/Cargo.toml b/aero-dav/Cargo.toml
index 92929b1..c847f68 100644
--- a/aero-dav/Cargo.toml
+++ b/aero-dav/Cargo.toml
@@ -12,3 +12,4 @@ http.workspace = true
chrono.workspace = true
tokio.workspace = true
futures.workspace = true
+tracing.workspace = true
diff --git a/aero-dav/src/caldecoder.rs b/aero-dav/src/caldecoder.rs
index ff79845..0df867f 100644
--- a/aero-dav/src/caldecoder.rs
+++ b/aero-dav/src/caldecoder.rs
@@ -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 ---
impl QRead<Violation> for Violation {
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
diff --git a/aero-dav/src/calencoder.rs b/aero-dav/src/calencoder.rs
index 48c93d0..a41747f 100644
--- a/aero-dav/src/calencoder.rs
+++ b/aero-dav/src/calencoder.rs
@@ -33,6 +33,25 @@ impl<E: Extension> QWrite for MkCalendarResponse<E> {
}
// ----------------------- 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> {
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
match self {
diff --git a/aero-dav/src/caltypes.rs b/aero-dav/src/caltypes.rs
index a763653..a4f6fef 100644
--- a/aero-dav/src/caltypes.rs
+++ b/aero-dav/src/caltypes.rs
@@ -51,6 +51,13 @@ pub struct MkCalendarResponse<E: dav::Extension>(pub Vec<dav::PropStat<E>>);
// --- (REPORT PART) ---
#[derive(Debug, PartialEq, Clone)]
+pub enum ReportTypeName {
+ Query,
+ Multiget,
+ FreeBusy,
+}
+
+#[derive(Debug, PartialEq, Clone)]
pub enum ReportType<E: dav::Extension> {
Query(CalendarQuery<E>),
Multiget(CalendarMultiget<E>),
diff --git a/aero-dav/src/realization.rs b/aero-dav/src/realization.rs
index 0f3aec4..b37e0f1 100644
--- a/aero-dav/src/realization.rs
+++ b/aero-dav/src/realization.rs
@@ -3,6 +3,7 @@ use super::caltypes as cal;
use super::error;
use super::synctypes as sync;
use super::types as dav;
+use super::versioningtypes as vers;
use super::xml;
#[derive(Debug, PartialEq, Clone)]
@@ -33,6 +34,7 @@ impl dav::Extension for Core {
type PropertyRequest = Disabled;
type ResourceType = Disabled;
type ReportType = Disabled;
+ type ReportTypeName = Disabled;
}
// WebDAV with the base Calendar implementation (RFC4791)
@@ -44,6 +46,7 @@ impl dav::Extension for Calendar {
type PropertyRequest = cal::PropertyRequest;
type ResourceType = cal::ResourceType;
type ReportType = cal::ReportType<Calendar>;
+ type ReportTypeName = cal::ReportTypeName;
}
// ACL
@@ -55,6 +58,7 @@ impl dav::Extension for Acl {
type PropertyRequest = acl::PropertyRequest;
type ResourceType = acl::ResourceType;
type ReportType = Disabled;
+ type ReportTypeName = Disabled;
}
// All merged
@@ -62,27 +66,38 @@ impl dav::Extension for Acl {
pub struct All {}
impl dav::Extension for All {
type Error = cal::Violation;
- type Property = Property;
+ type Property = Property<All>;
type PropertyRequest = PropertyRequest;
type ResourceType = ResourceType;
type ReportType = ReportType<All>;
+ type ReportTypeName = ReportTypeName;
}
#[derive(Debug, PartialEq, Clone)]
-pub enum Property {
+pub enum Property<E: dav::Extension> {
Cal(cal::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> {
match cal::Property::qread(xml).await {
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(
&self,
xml: &mut xml::Writer<impl xml::IWrite>,
@@ -90,6 +105,8 @@ impl xml::QWrite for Property {
match self {
Self::Cal(c) => c.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 {
Cal(cal::PropertyRequest),
Acl(acl::PropertyRequest),
+ Sync(sync::PropertyRequest),
+ Vers(vers::PropertyRequest),
}
impl xml::QRead<PropertyRequest> for PropertyRequest {
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) => (),
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
- .map(PropertyRequest::Acl)
+ .map(PropertyRequest::Vers)
}
}
impl xml::QWrite for PropertyRequest {
@@ -118,6 +145,8 @@ impl xml::QWrite for PropertyRequest {
match self {
Self::Cal(c) => c.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,
+ }
+ }
+}
diff --git a/aero-dav/src/syncdecoder.rs b/aero-dav/src/syncdecoder.rs
index 8e035ab..d81f8d4 100644
--- a/aero-dav/src/syncdecoder.rs
+++ b/aero-dav/src/syncdecoder.rs
@@ -5,6 +5,34 @@ use super::synctypes::*;
use super::types as dav;
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> {
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
xml.open(DAV_URN, "sync-collection").await?;
@@ -75,7 +103,7 @@ impl QRead<SyncLevel> for SyncLevel {
#[cfg(test)]
mod tests {
use super::*;
- use crate::realization::All;
+ use crate::realization::{self, All};
use crate::types as dav;
use crate::versioningtypes as vers;
use crate::xml::Node;
@@ -172,4 +200,42 @@ mod tests {
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);
+ }
}
diff --git a/aero-dav/src/syncencoder.rs b/aero-dav/src/syncencoder.rs
index 22b288b..59ad6cc 100644
--- a/aero-dav/src/syncencoder.rs
+++ b/aero-dav/src/syncencoder.rs
@@ -5,6 +5,33 @@ use super::synctypes::*;
use super::types::Extension;
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> {
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
let start = xml.create_dav_element("sync-collection");
@@ -72,7 +99,7 @@ impl QWrite for SyncLevel {
#[cfg(test)]
mod tests {
use super::*;
- use crate::realization::All;
+ use crate::realization::{self, All};
use crate::types as dav;
use crate::versioningtypes as vers;
use crate::xml::Node;
@@ -92,6 +119,7 @@ mod tests {
src.qwrite(&mut writer).await.expect("xml serialization");
tokio_buffer.flush().await.expect("tokio buffer flush");
let got = std::str::from_utf8(buffer.as_slice()).unwrap();
+ println!("{:?}", got);
// deserialize
let mut rdr = Reader::new(quick_xml::NsReader::from_reader(got.as_bytes()))
@@ -141,4 +169,31 @@ mod tests {
})
.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;
+ }
}
diff --git a/aero-dav/src/synctypes.rs b/aero-dav/src/synctypes.rs
index a2f40bd..c127962 100644
--- a/aero-dav/src/synctypes.rs
+++ b/aero-dav/src/synctypes.rs
@@ -4,8 +4,21 @@ use super::versioningtypes as vers;
// RFC 6578
// https://datatracker.ietf.org/doc/html/rfc6578
-//@FIXME add SyncTokenRequest to PropertyRequest
-//@FIXME add SyncToken to Property
+#[derive(Debug, PartialEq, Clone)]
+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
/// Name: sync-collection
diff --git a/aero-dav/src/types.rs b/aero-dav/src/types.rs
index 6039a26..92c63e0 100644
--- a/aero-dav/src/types.rs
+++ b/aero-dav/src/types.rs
@@ -12,6 +12,7 @@ pub trait Extension: std::fmt::Debug + PartialEq + Clone {
type PropertyRequest: xml::Node<Self::PropertyRequest>;
type ResourceType: xml::Node<Self::ResourceType>;
type ReportType: xml::Node<Self::ReportType>;
+ type ReportTypeName: xml::Node<Self::ReportTypeName>;
}
/// 14.1. activelock XML Element
diff --git a/aero-dav/src/versioningdecoder.rs b/aero-dav/src/versioningdecoder.rs
index 4816cf1..9e58d8c 100644
--- a/aero-dav/src/versioningdecoder.rs
+++ b/aero-dav/src/versioningdecoder.rs
@@ -3,12 +3,87 @@ use super::types as dav;
use super::versioningtypes::*;
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> {
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Self, ParsingError> {
- //@FIXME VersionTree not implemented
- //@FIXME ExpandTree not implemented
+ xml.open(DAV_URN, "report").await?;
- E::ReportType::qread(xml).await.map(Report::Extension)
+ 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)
+ };
+
+ xml.close().await?;
+ final_result
}
}
diff --git a/aero-dav/src/versioningencoder.rs b/aero-dav/src/versioningencoder.rs
index bd40f1b..c061f07 100644
--- a/aero-dav/src/versioningencoder.rs
+++ b/aero-dav/src/versioningencoder.rs
@@ -5,6 +5,67 @@ use super::types::Extension;
use super::versioningtypes::*;
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> {
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
match self {
@@ -15,6 +76,7 @@ impl<E: Extension> QWrite for Report<E> {
}
}
+// --- limit REPORT parameter ---
impl QWrite for Limit {
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
let start = xml.create_dav_element("limit");
diff --git a/aero-dav/src/versioningtypes.rs b/aero-dav/src/versioningtypes.rs
index ba64b05..1f8d1cf 100644
--- a/aero-dav/src/versioningtypes.rs
+++ b/aero-dav/src/versioningtypes.rs
@@ -22,6 +22,26 @@ use super::types as dav;
// 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)]
pub enum Report<E: dav::Extension> {
VersionTree, // Not yet implemented
ExpandProperty, // Not yet implemented