WIP XML encoder
This commit is contained in:
parent
ffe4d071f6
commit
9146537aaf
2 changed files with 61 additions and 7 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue