diff options
Diffstat (limited to 'aero-dav/src/encoder.rs')
-rw-r--r-- | aero-dav/src/encoder.rs | 114 |
1 files changed, 69 insertions, 45 deletions
diff --git a/aero-dav/src/encoder.rs b/aero-dav/src/encoder.rs index 3b0bfda..1320c8a 100644 --- a/aero-dav/src/encoder.rs +++ b/aero-dav/src/encoder.rs @@ -48,7 +48,7 @@ impl<E: Extension> QWrite for PropertyUpdate<E> { /// PROPFIND RESPONSE, PROPPATCH RESPONSE, COPY RESPONSE, MOVE RESPONSE /// DELETE RESPONSE, -impl<E: Extension, N: Node<N>> QWrite for Multistatus<E,N> { +impl<E: Extension> QWrite for Multistatus<E> { async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> { let start = xml.create_dav_element("multistatus"); let end = start.to_end(); @@ -154,6 +154,28 @@ impl<E: Extension> QWrite for PropName<E> { } } +impl<E: Extension> QWrite for AnyProp<E> { + async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> { + let start = xml.create_dav_element("prop"); + let end = start.to_end(); + + xml.q.write_event_async(Event::Start(start.clone())).await?; + for propname in &self.0 { + propname.qwrite(xml).await?; + } + xml.q.write_event_async(Event::End(end)).await + } +} + +impl<E: Extension> QWrite for AnyProperty<E> { + async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> { + match self { + Self::Request(v) => v.qwrite(xml).await, + Self::Value(v) => v.qwrite(xml).await, + } + } +} + impl QWrite for Href { async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> { @@ -166,7 +188,7 @@ impl QWrite for Href { } } -impl<E: Extension, N: Node<N>> QWrite for Response<E,N> { +impl<E: Extension> QWrite for Response<E> { async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> { let start = xml.create_dav_element("response"); let end = start.to_end(); @@ -186,7 +208,7 @@ impl<E: Extension, N: Node<N>> QWrite for Response<E,N> { } } -impl<E: Extension, N: Node<N>> QWrite for StatusOrPropstat<E,N> { +impl<E: Extension> QWrite for StatusOrPropstat<E> { async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> { match self { Self::Status(many_href, status) => { @@ -244,7 +266,7 @@ impl QWrite for Location { } } -impl<E: Extension, N: Node<N>> QWrite for PropStat<E,N> { +impl<E: Extension> QWrite for PropStat<E> { async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> { let start = xml.create_dav_element("propstat"); let end = start.to_end(); @@ -672,7 +694,7 @@ mod tests { #[tokio::test] async fn basic_multistatus() { - let orig = Multistatus::<Core, PropName<Core>> { + let orig = Multistatus::<Core> { responses: vec![], responsedescription: Some(ResponseDescription("Hello world".into())) }; @@ -683,7 +705,7 @@ mod tests { </D:multistatus>"#; assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n"); - assert_eq!(deserialize::<Multistatus::<Core, PropName<Core>>>(got.as_str()).await, orig) + assert_eq!(deserialize::<Multistatus::<Core>>(got.as_str()).await, orig) } @@ -722,17 +744,17 @@ mod tests { #[tokio::test] async fn rfc_propname_res() { - let orig = Multistatus::<Core, PropName<Core>> { + let orig = Multistatus::<Core> { responses: vec![ Response { status_or_propstat: StatusOrPropstat::PropStat( Href("http://www.example.com/container/".into()), vec![PropStat { - prop: PropName(vec![ - PropertyRequest::CreationDate, - PropertyRequest::DisplayName, - PropertyRequest::ResourceType, - PropertyRequest::SupportedLock, + prop: AnyProp(vec![ + AnyProperty::Request(PropertyRequest::CreationDate), + AnyProperty::Request(PropertyRequest::DisplayName), + AnyProperty::Request(PropertyRequest::ResourceType), + AnyProperty::Request(PropertyRequest::SupportedLock), ]), status: Status(http::status::StatusCode::OK), error: None, @@ -747,15 +769,15 @@ mod tests { status_or_propstat: StatusOrPropstat::PropStat( Href("http://www.example.com/container/front.html".into()), vec![PropStat { - prop: PropName(vec![ - PropertyRequest::CreationDate, - PropertyRequest::DisplayName, - PropertyRequest::GetContentLength, - PropertyRequest::GetContentType, - PropertyRequest::GetEtag, - PropertyRequest::GetLastModified, - PropertyRequest::ResourceType, - PropertyRequest::SupportedLock, + prop: AnyProp(vec![ + AnyProperty::Request(PropertyRequest::CreationDate), + AnyProperty::Request(PropertyRequest::DisplayName), + AnyProperty::Request(PropertyRequest::GetContentLength), + AnyProperty::Request(PropertyRequest::GetContentType), + AnyProperty::Request(PropertyRequest::GetEtag), + AnyProperty::Request(PropertyRequest::GetLastModified), + AnyProperty::Request(PropertyRequest::ResourceType), + AnyProperty::Request(PropertyRequest::SupportedLock), ]), status: Status(http::status::StatusCode::OK), error: None, @@ -805,7 +827,7 @@ mod tests { assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n"); - assert_eq!(deserialize::<Multistatus::<Core, PropName<Core>>>(got.as_str()).await, orig) + assert_eq!(deserialize::<Multistatus::<Core>>(got.as_str()).await, orig) } #[tokio::test] @@ -825,20 +847,20 @@ mod tests { async fn rfc_allprop_res() { use chrono::{FixedOffset,TimeZone}; - let orig = Multistatus::<Core, PropValue<Core>> { + let orig = Multistatus::<Core> { responses: vec![ Response { status_or_propstat: StatusOrPropstat::PropStat( Href("/container/".into()), vec![PropStat { - prop: PropValue(vec![ - Property::CreationDate(FixedOffset::west_opt(8 * 3600) + prop: AnyProp(vec![ + AnyProperty::Value(Property::CreationDate(FixedOffset::west_opt(8 * 3600) .unwrap() .with_ymd_and_hms(1997, 12, 1, 17, 42, 21) - .unwrap()), - Property::DisplayName("Example collection".into()), - Property::ResourceType(vec![ResourceType::Collection]), - Property::SupportedLock(vec![ + .unwrap())), + AnyProperty::Value(Property::DisplayName("Example collection".into())), + AnyProperty::Value(Property::ResourceType(vec![ResourceType::Collection])), + AnyProperty::Value(Property::SupportedLock(vec![ LockEntry { lockscope: LockScope::Exclusive, locktype: LockType::Write, @@ -847,7 +869,7 @@ mod tests { lockscope: LockScope::Shared, locktype: LockType::Write, }, - ]), + ])), ]), status: Status(http::status::StatusCode::OK), error: None, @@ -862,21 +884,23 @@ mod tests { status_or_propstat: StatusOrPropstat::PropStat( Href("/container/front.html".into()), vec![PropStat { - prop: PropValue(vec![ - Property::CreationDate(FixedOffset::west_opt(8 * 3600) + prop: AnyProp(vec![ + AnyProperty::Value(Property::CreationDate(FixedOffset::west_opt(8 * 3600) .unwrap() .with_ymd_and_hms(1997, 12, 1, 18, 27, 21) - .unwrap()), - Property::DisplayName("Example HTML resource".into()), - Property::GetContentLength(4525), - Property::GetContentType("text/html".into()), - Property::GetEtag(r#""zzyzx""#.into()), - Property::GetLastModified(FixedOffset::east_opt(0) + .unwrap())), + AnyProperty::Value(Property::DisplayName("Example HTML resource".into())), + AnyProperty::Value(Property::GetContentLength(4525)), + AnyProperty::Value(Property::GetContentType("text/html".into())), + AnyProperty::Value(Property::GetEtag(r#""zzyzx""#.into())), + AnyProperty::Value(Property::GetLastModified(FixedOffset::east_opt(0) .unwrap() .with_ymd_and_hms(1998, 1, 12, 9, 25, 56) - .unwrap()), - Property::ResourceType(vec![]), - Property::SupportedLock(vec![ + .unwrap())), + //@FIXME know bug, can't disambiguate between an empty resource + //type value and a request resource type + AnyProperty::Request(PropertyRequest::ResourceType), + AnyProperty::Value(Property::SupportedLock(vec![ LockEntry { lockscope: LockScope::Exclusive, locktype: LockType::Write, @@ -885,7 +909,7 @@ mod tests { lockscope: LockScope::Shared, locktype: LockType::Write, }, - ]), + ])), ]), status: Status(http::status::StatusCode::OK), error: None, @@ -970,7 +994,7 @@ mod tests { </D:multistatus>"#; assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n"); - assert_eq!(deserialize::<Multistatus::<Core, PropValue<Core>>>(got.as_str()).await, orig) + assert_eq!(deserialize::<Multistatus::<Core>>(got.as_str()).await, orig) } #[tokio::test] @@ -1025,7 +1049,7 @@ mod tests { #[tokio::test] async fn rfc_delete_locked2() { - let orig = Multistatus::<Core, PropValue<Core>> { + let orig = Multistatus::<Core> { responses: vec![Response { status_or_propstat: StatusOrPropstat::Status( vec![Href("http://www.example.com/container/resource3".into())], @@ -1051,7 +1075,7 @@ mod tests { </D:multistatus>"#; assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n"); - assert_eq!(deserialize::<Multistatus::<Core, PropValue<Core>>>(got.as_str()).await, orig) + assert_eq!(deserialize::<Multistatus::<Core>>(got.as_str()).await, orig) } #[tokio::test] |