diff --git a/crates/caldav/src/lib.rs b/crates/caldav/src/lib.rs index 5c86a15..b574300 100644 --- a/crates/caldav/src/lib.rs +++ b/crates/caldav/src/lib.rs @@ -48,7 +48,7 @@ pub fn caldav_service< HeaderName::from_static("dav"), // https://datatracker.ietf.org/doc/html/rfc4918#section-18 HeaderValue::from_static( - "1, 3, access-control, calendar-access, extended-mkcol, calendar-no-timezone", + "1, 3, access-control, calendar-access, extended-mkcol, calendar-no-timezone, webdav-push", ), )); diff --git a/crates/carddav/src/lib.rs b/crates/carddav/src/lib.rs index 0fa1b48..f4adc46 100644 --- a/crates/carddav/src/lib.rs +++ b/crates/carddav/src/lib.rs @@ -41,7 +41,7 @@ pub fn carddav_service String { + match self { + Depth::Zero => "0", + Depth::One => "1", + Depth::Infinity => "Infinity", + } + .to_owned() + } +} + impl TryFrom<&[u8]> for Depth { type Error = InvalidDepthHeader; diff --git a/crates/dav_push/src/extension.rs b/crates/dav_push/src/extension.rs index 988e869..2b0d28e 100644 --- a/crates/dav_push/src/extension.rs +++ b/crates/dav_push/src/extension.rs @@ -1,4 +1,5 @@ -use crate::Transports; +use crate::{ContentUpdate, PropertyUpdate, SupportedTrigger, SupportedTriggers, Transports}; +use rustical_dav::header::Depth; use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize}; #[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone, EnumUnitVariants, EnumVariants)] @@ -10,11 +11,21 @@ pub enum DavPushExtensionProp { Transports(Transports), #[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")] Topic(String), + #[xml(skip_deserializing)] + #[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")] + SupportedTriggers(SupportedTriggers), } pub trait DavPushExtension { fn get_topic(&self) -> String; + fn supported_triggers(&self) -> SupportedTriggers { + SupportedTriggers(vec![ + SupportedTrigger::ContentUpdate(ContentUpdate(Depth::One)), + SupportedTrigger::PropertyUpdate(PropertyUpdate(Depth::One)), + ]) + } + fn get_prop( &self, prop: &DavPushExtensionPropName, @@ -24,6 +35,9 @@ pub trait DavPushExtension { DavPushExtensionProp::Transports(Default::default()) } DavPushExtensionPropName::Topic => DavPushExtensionProp::Topic(self.get_topic()), + DavPushExtensionPropName::SupportedTriggers => { + DavPushExtensionProp::SupportedTriggers(self.supported_triggers()) + } }) } diff --git a/crates/dav_push/src/prop.rs b/crates/dav_push/src/prop.rs index 5a3ea2a..f596562 100644 --- a/crates/dav_push/src/prop.rs +++ b/crates/dav_push/src/prop.rs @@ -1,3 +1,4 @@ +use rustical_dav::header::Depth; use rustical_xml::XmlSerialize; #[derive(Debug, Clone, XmlSerialize, PartialEq)] @@ -20,3 +21,24 @@ impl Default for Transports { } } } + +#[derive(XmlSerialize, PartialEq, Clone)] +pub struct SupportedTriggers(#[xml(flatten, ty = "untagged")] pub Vec); + +#[derive(XmlSerialize, PartialEq, Clone)] +pub enum SupportedTrigger { + #[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")] + ContentUpdate(ContentUpdate), + #[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")] + PropertyUpdate(PropertyUpdate), +} + +#[derive(XmlSerialize, PartialEq, Clone)] +pub struct ContentUpdate( + #[xml(rename = b"depth", ns = "rustical_dav::namespace::NS_DAV")] pub Depth, +); + +#[derive(XmlSerialize, PartialEq, Clone)] +pub struct PropertyUpdate( + #[xml(rename = b"depth", ns = "rustical_dav::namespace::NS_DAV")] pub Depth, +);