diff --git a/crates/dav/src/xml/tag_list.rs b/crates/dav/src/xml/tag_list.rs index 0d07827..461e511 100644 --- a/crates/dav/src/xml/tag_list.rs +++ b/crates/dav/src/xml/tag_list.rs @@ -1,5 +1,8 @@ use derive_more::derive::From; -use quick_xml::name::Namespace; +use quick_xml::{ + events::{BytesEnd, BytesStart, Event}, + name::Namespace, +}; use rustical_xml::{NamespaceOwned, XmlSerialize}; use std::collections::HashMap; @@ -9,11 +12,37 @@ pub struct TagList(Vec<(Option, String)>); impl XmlSerialize for TagList { fn serialize( &self, - _ns: Option, - _tag: Option<&[u8]>, - _namespaces: &HashMap, + ns: Option, + tag: Option<&[u8]>, + namespaces: &HashMap, writer: &mut quick_xml::Writer, ) -> std::io::Result<()> { + let prefix = ns + .map(|ns| namespaces.get(&ns)) + .unwrap_or(None) + .map(|prefix| { + if !prefix.is_empty() { + [*prefix, b":"].concat() + } else { + Vec::new() + } + }); + let has_prefix = prefix.is_some(); + let tagname = tag.map(|tag| [&prefix.unwrap_or_default(), tag].concat()); + let qname = tagname + .as_ref() + .map(|tagname| ::quick_xml::name::QName(tagname)); + + if let Some(qname) = &qname { + let mut bytes_start = BytesStart::from(qname.to_owned()); + if !has_prefix { + if let Some(ns) = &ns { + bytes_start.push_attribute((b"xmlns".as_ref(), ns.as_ref())); + } + } + writer.write_event(Event::Start(bytes_start))?; + } + for (ns, tag) in &self.0 { let mut el = writer.create_element(tag); if let Some(ns) = ns { @@ -21,6 +50,10 @@ impl XmlSerialize for TagList { } el.write_empty()?; } + + if let Some(qname) = &qname { + writer.write_event(Event::End(BytesEnd::from(qname.to_owned())))?; + } Ok(()) }