diff --git a/src/dav/encoder.rs b/src/dav/encoder.rs index 9e907dc..4a9bcf4 100644 --- a/src/dav/encoder.rs +++ b/src/dav/encoder.rs @@ -72,21 +72,20 @@ impl QuickWritable for PropFind { include.write(xml, ctx.child()).await?; } }, - Self::Prop(many_propreq) => { - let start = ctx.create_dav_element("prop"); - let end = start.to_end(); - - xml.write_event_async(Event::Start(start.clone())).await?; - for propreq in many_propreq.iter() { - propreq.write(xml, ctx.child()).await?; - } - xml.write_event_async(Event::End(end)).await?; - }, + Self::Prop(propname) => propname.write(xml, ctx.child()).await?, } xml.write_event_async(Event::End(end)).await } } +/// PROPPATCH REQUEST +impl QuickWritable for PropertyUpdate { + async fn write(&self, xml: &mut Writer, ctx: C) -> Result<(), QError> { + unimplemented!(); + } +} + + /// PROPFIND RESPONSE, PROPPATCH RESPONSE, COPY RESPONSE, MOVE RESPONSE /// DELETE RESPONSE, impl QuickWritable for Multistatus { @@ -124,31 +123,43 @@ impl QuickWritable for LockInfo { } /// SOME LOCK RESPONSES -impl QuickWritable for Prop { +impl QuickWritable for PropValue { async fn write(&self, xml: &mut Writer, ctx: C) -> Result<(), QError> { let start = ctx.create_dav_element("prop"); let end = start.to_end(); xml.write_event_async(Event::Start(start.clone())).await?; - match self { - Self::Name(many_names) => { - for propname in many_names { - propname.write(xml, ctx.child()).await?; - } - }, - Self::Value(many_values) => { - for propval in many_values { - propval.write(xml, ctx.child()).await?; - } - } - }; - xml.write_event_async(Event::End(end)).await?; - - Ok(()) + for propval in &self.0 { + propval.write(xml, ctx.child()).await?; + } + xml.write_event_async(Event::End(end)).await } } // --- XML inner elements +impl QuickWritable for AnyProp { + async fn write(&self, xml: &mut Writer, ctx: C) -> Result<(), QError> { + match self { + Self::Name(propname) => propname.write(xml, ctx).await, + Self::Value(propval) => propval.write(xml, ctx).await, + } + } +} + +impl QuickWritable for PropName { + async fn write(&self, xml: &mut Writer, ctx: C) -> Result<(), QError> { + let start = ctx.create_dav_element("prop"); + let end = start.to_end(); + + xml.write_event_async(Event::Start(start.clone())).await?; + for propname in &self.0 { + propname.write(xml, ctx.child()).await?; + } + xml.write_event_async(Event::End(end)).await + } +} + + impl QuickWritable for Href { async fn write(&self, xml: &mut Writer, ctx: C) -> Result<(), QError> { let start = ctx.create_dav_element("href"); @@ -411,7 +422,7 @@ impl QuickWritable for Include { impl QuickWritable for PropertyRequest { async fn write(&self, xml: &mut Writer, ctx: C) -> Result<(), QError> { use PropertyRequest::*; - let mut atom = (async |c| xml.write_event_async(Event::Empty(ctx.create_dav_element(c))).await); + let mut atom = async |c| xml.write_event_async(Event::Empty(ctx.create_dav_element(c))).await; match self { CreationDate => atom("creationdate").await, @@ -724,12 +735,12 @@ mod tests { Response { href: Href("http://www.example.com/container/".into()), status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { - prop: Prop::Name(vec![ + prop: AnyProp::Name(PropName(vec![ PropertyRequest::CreationDate, PropertyRequest::DisplayName, PropertyRequest::ResourceType, PropertyRequest::SupportedLock, - ]), + ])), status: Status(http::status::StatusCode::OK), error: None, responsedescription: None, @@ -741,7 +752,7 @@ mod tests { Response { href: Href("http://www.example.com/container/front.html".into()), status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { - prop: Prop::Name(vec![ + prop: AnyProp::Name(PropName(vec![ PropertyRequest::CreationDate, PropertyRequest::DisplayName, PropertyRequest::GetContentLength, @@ -750,7 +761,7 @@ mod tests { PropertyRequest::GetLastModified, PropertyRequest::ResourceType, PropertyRequest::SupportedLock, - ]), + ])), status: Status(http::status::StatusCode::OK), error: None, responsedescription: None, @@ -823,7 +834,7 @@ mod tests { Response { href: Href("/container/".into()), status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { - prop: Prop::Value(vec![ + prop: AnyProp::Value(PropValue(vec![ Property::CreationDate(FixedOffset::west_opt(8 * 3600) .unwrap() .with_ymd_and_hms(1997, 12, 1, 17, 42, 21) @@ -840,7 +851,7 @@ mod tests { locktype: LockType::Write, }, ]), - ]), + ])), status: Status(http::status::StatusCode::OK), error: None, responsedescription: None, @@ -852,7 +863,7 @@ mod tests { Response { href: Href("/container/front.html".into()), status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { - prop: Prop::Value(vec![ + prop: AnyProp::Value(PropValue(vec![ Property::CreationDate(FixedOffset::west_opt(8 * 3600) .unwrap() .with_ymd_and_hms(1997, 12, 1, 18, 27, 21) @@ -876,7 +887,7 @@ mod tests { locktype: LockType::Write, }, ]), - ]), + ])), status: Status(http::status::StatusCode::OK), error: None, responsedescription: None, @@ -981,4 +992,30 @@ mod tests { assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n"); } + + #[tokio::test] + async fn rfc_propertyupdate() { + let got = serialize( + NoExtension { root: true }, + &PropertyUpdate(vec![ + PropertyUpdateItem::Set(Set(PropValue(vec![ ]))), + PropertyUpdateItem::Remove(Remove(PropName(vec![]))), + ]), + ).await; + + let expected = r#" + + + fr-FR + + + + + + + +"#; + + assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n"); + } } diff --git a/src/dav/types.rs b/src/dav/types.rs index 55e9e86..4487de7 100644 --- a/src/dav/types.rs +++ b/src/dav/types.rs @@ -372,10 +372,12 @@ pub struct Owner { /// text or mixed content. /// /// -pub enum Prop { - Name(Vec>), - Value(Vec>), +pub enum AnyProp { + Name(PropName), + Value(PropValue), } +pub struct PropName(pub Vec>); +pub struct PropValue(pub Vec>); /// 14.19. propertyupdate XML Element /// @@ -387,7 +389,7 @@ pub enum Prop { /// required to modify the properties on the resource. /// /// -pub struct PropertyUpdate(Vec>); +pub struct PropertyUpdate(pub Vec>); pub enum PropertyUpdateItem { Remove(Remove), Set(Set), @@ -430,7 +432,7 @@ pub enum PropertyUpdateItem { pub enum PropFind { PropName, AllProp(Option>), - Prop(Vec>), + Prop(PropName), } @@ -451,7 +453,7 @@ pub enum PropFind { /// /// pub struct PropStat { - pub prop: Prop, + pub prop: AnyProp, pub status: Status, pub error: Option>, pub responsedescription: Option, @@ -470,7 +472,7 @@ pub struct PropStat { /// the names of properties to be removed are required. /// /// -pub struct Remove(pub Prop); +pub struct Remove(pub PropName); /// 14.24. response XML Element /// @@ -535,7 +537,7 @@ pub struct ResponseDescription(pub String); /// property, and MUST be subsequently retrievable using PROPFIND. /// /// -pub struct Set(pub Prop); +pub struct Set(pub PropValue); /// 14.27. shared XML Element ///