diff --git a/crates/xml/derive/src/xml_struct.rs b/crates/xml/derive/src/xml_struct.rs index f7dd8fb..7b9adeb 100644 --- a/crates/xml/derive/src/xml_struct.rs +++ b/crates/xml/derive/src/xml_struct.rs @@ -185,6 +185,7 @@ impl NamedStruct { .fields .iter() .filter(|field| field.attrs.xml_ty == FieldType::Untagged) + .filter(|field| !field.attrs.flatten.is_present()) .map(|field| { let field_ident = field.field_ident(); quote! { @@ -209,6 +210,17 @@ impl NamedStruct { } }); + let tag_name_field = self + .fields + .iter() + .find(|field| field.attrs.xml_ty == FieldType::TagName) + .map(|field| { + let field_ident = field.field_ident(); + quote! { + let tag_str = Some(tag_str.unwrap_or(self.#field_ident.to_string())); + } + }); + quote! { impl #impl_generics ::rustical_xml::XmlSerialize for #ident #type_generics #where_clause { fn serialize( @@ -219,14 +231,15 @@ impl NamedStruct { ) -> ::std::io::Result<()> { use ::quick_xml::events::{BytesEnd, BytesStart, BytesText, Event}; - let tag_str = tag.map(String::from_utf8_lossy); + let tag_str = tag.map(|a| String::from_utf8_lossy(a).to_string()); + #tag_name_field; if let Some(tag) = &tag_str { let mut bytes_start = BytesStart::new(tag.to_owned()); if let Some(attrs) = self.attributes() { bytes_start.extend_attributes(attrs); } - // #(#untagged_attributes);* + #(#untagged_attributes);* writer.write_event(Event::Start(bytes_start))?; } #(#tag_writers);* diff --git a/crates/xml/src/value.rs b/crates/xml/src/value.rs index 3422afb..4fe514b 100644 --- a/crates/xml/src/value.rs +++ b/crates/xml/src/value.rs @@ -50,6 +50,16 @@ impl_value_parse!(u64); impl_value_parse!(isize); impl_value_parse!(usize); +impl Value for &str { + fn serialize(&self) -> String { + self.to_string() + } + + fn deserialize(val: &str) -> Result { + Err(XmlDeError::Other("TODO: Handle this error".to_owned())) + } +} + impl XmlDeserialize for T { fn deserialize( reader: &mut quick_xml::NsReader, diff --git a/crates/xml/tests/se_struct.rs b/crates/xml/tests/se_struct.rs index ed53f2c..5990761 100644 --- a/crates/xml/tests/se_struct.rs +++ b/crates/xml/tests/se_struct.rs @@ -1,5 +1,7 @@ +use std::borrow::{Borrow, Cow}; + use quick_xml::Writer; -use rustical_xml::{XmlRootTag, XmlSerialize, XmlSerializeRoot}; +use rustical_xml::{XmlDocument, XmlRootTag, XmlSerialize, XmlSerializeRoot}; use xml_derive::XmlDeserialize; #[test] @@ -132,7 +134,7 @@ fn test_struct_serialize_with() { } fn serialize_href( - val: &String, + val: &str, ns: Option<&[u8]>, tag: Option<&[u8]>, writer: &mut Writer, @@ -150,3 +152,39 @@ fn test_struct_serialize_with() { let out = String::from_utf8(buf).unwrap(); assert_eq!(out, "OKAY"); } + +#[test] +fn test_struct_tag_list() { + #[derive(Debug, XmlRootTag, XmlSerialize, XmlDeserialize, PartialEq)] + #[xml(root = b"document")] + struct Document { + #[xml(ty = "untagged", flatten)] + tags: Vec, + } + + #[derive(Debug, XmlSerialize, XmlDeserialize, PartialEq)] + struct Tag { + #[xml(ty = "tag_name")] + name: String, + } + + let mut buf = Vec::new(); + let mut writer = quick_xml::Writer::new(&mut buf); + Document { + tags: vec![ + Tag { + name: "hello".to_owned(), + }, + Tag { + name: "ok".to_owned(), + }, + Tag { + name: "wow".to_owned(), + }, + ], + } + .serialize_root(&mut writer) + .unwrap(); + let out = String::from_utf8(buf).unwrap(); + dbg!(out); +}