aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dav/encoder.rs59
-rw-r--r--src/dav/types.rs7
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