diff options
Diffstat (limited to 'src/dav')
-rw-r--r-- | src/dav/encoder.rs | 59 | ||||
-rw-r--r-- | src/dav/types.rs | 7 |
2 files changed, 60 insertions, 6 deletions
diff --git a/src/dav/encoder.rs b/src/dav/encoder.rs index 28f807a..552f183 100644 --- a/src/dav/encoder.rs +++ b/src/dav/encoder.rs @@ -1,6 +1,7 @@ use std::io::Cursor; -use anyhow::Result; +use futures::stream::{StreamExt, TryStreamExt}; +use quick_xml::Error; use quick_xml::events::{Event, BytesEnd, BytesStart, BytesText}; use quick_xml::writer::{ElementWriter, Writer}; use quick_xml::name::PrefixDeclaration; @@ -12,19 +13,52 @@ use super::types::*; //So instead of writing many cursed workarounds - I tried, I am just hardcoding the namespaces... pub trait Encode { - async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<()>; + async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<(), Error>; } impl Encode for Href { - async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<()> { + async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<(), Error> { xml.create_element("D:href") .write_text_content_async(BytesText::new(&self.0)) .await?; + Ok(()) + } +} +impl<T> Encode for Multistatus<T> { + async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<(), Error> { + xml.create_element("D:multistatus") + .with_attribute(("xmlns:D", "DAV:")) + .write_inner_content_async::<_, _, quick_xml::Error>(|inner_xml| async move { + for response in self.responses.iter() { + response.write(inner_xml).await?; + } + + if let Some(description) = &self.responsedescription { + description.write(inner_xml).await?; + } + + Ok(inner_xml) + }) + .await?; Ok(()) } } +impl<T> Encode for Response<T> { + async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<(), Error> { + unimplemented!(); + } +} + +impl Encode for ResponseDescription { + async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<(), Error> { + xml.create_element("D:responsedescription") + .write_text_content_async(BytesText::new(&self.0)) + .await?; + Ok(()) + } +} #[cfg(test)] mod tests { @@ -45,4 +79,23 @@ mod tests { assert_eq!(buffer.as_slice(), &b"<D:href>/SOGo/dav/so/</D:href>"[..]); } + + + #[tokio::test] + async fn test_multistatus() { + let mut buffer = Vec::new(); + let mut tokio_buffer = tokio::io::BufWriter::new(&mut buffer); + let mut writer = Writer::new_with_indent(&mut tokio_buffer, b' ', 4); + + let xml: Multistatus<u64> = Multistatus { responses: vec![], responsedescription: Some(ResponseDescription("Hello world".into())) }; + xml.write(&mut writer).await.expect("xml serialization"); + tokio_buffer.flush().await.expect("tokio buffer flush"); + + let expected = r#"<D:multistatus xmlns:D="DAV:"> + <D:responsedescription>Hello world</D:responsedescription> +</D:multistatus>"#; + let got = std::str::from_utf8(buffer.as_slice()).unwrap(); + + assert_eq!(got, expected); + } } diff --git a/src/dav/types.rs b/src/dav/types.rs index 1ff690f..7bbea8e 100644 --- a/src/dav/types.rs +++ b/src/dav/types.rs @@ -313,8 +313,8 @@ pub enum LockType { /// /// <!ELEMENT multistatus (response*, responsedescription?) > pub struct Multistatus<T> { - responses: Vec<Response<T>>, - responsedescription: Option<ResponseDescription>, + pub responses: Vec<Response<T>>, + pub responsedescription: Option<ResponseDescription>, } /// 14.17. owner XML Element @@ -480,7 +480,7 @@ pub struct Response<T> { /// user. /// /// <!ELEMENT responsedescription (#PCDATA) > -pub struct ResponseDescription(String); +pub struct ResponseDescription(pub String); /// 14.26. set XML Element /// @@ -573,6 +573,7 @@ pub enum PropertyRequest { GetLastModified, LockDiscovery, ResourceType, + SupportedLock, } pub enum Property { /// 15.1. creationdate Property |