Skip to content

Commit

Permalink
Fix the serialization when untagged fields found
Browse files Browse the repository at this point in the history
  • Loading branch information
ImJeremyHe committed Nov 8, 2024
1 parent 75c36bd commit 03ab237
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
8 changes: 6 additions & 2 deletions derives/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ fn get_ser_struct_impl_block(container: Container) -> proc_macro2::TokenStream {
let write_event = quote! {
if is_empty {
writer.write_event(Event::Empty(start));
} else if is_untagged {
// Not to write the start event
#write_text_or_children
} else {
writer.write_event(Event::Start(start));
#write_text_or_children
Expand Down Expand Up @@ -224,6 +227,7 @@ fn get_ser_struct_impl_block(container: Container) -> proc_macro2::TokenStream {
use ::xmlserde::XmlValue;
let start = BytesStart::new(String::from_utf8_lossy(tag));
let mut attrs = Vec::<Attribute>::new();
let is_untagged = tag.len() == 0;
#write_ns
#write_custom_ns
#(#build_attr_and_push)*
Expand Down Expand Up @@ -259,7 +263,7 @@ fn init_is_empty(
},
}
});
let has_untags = untags.len() > 0;
let has_untag_fields = untags.len() > 0;
let scf_init = scf.iter().map(|s| {
let ident = s.original.ident.as_ref().unwrap();
quote! {
Expand Down Expand Up @@ -297,7 +301,7 @@ fn init_is_empty(
});
quote! {
let has_child_to_write = #(#idents ||)* has_text;
let is_empty = !has_child_to_write && !#has_untags;
let is_empty = !has_child_to_write && !#has_untag_fields;
}
};
quote! {
Expand Down
44 changes: 37 additions & 7 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ mod tests {
#[derive(XmlDeserialize, Default)]
pub struct Child {
#[xmlserde(name = b"age", ty = "attr")]
pub age: u16,
pub _age: u16,
#[xmlserde(ty = "text")]
pub name: String,
pub _name: String,
}
fn default_zero() -> u32 {
0
Expand All @@ -158,7 +158,7 @@ mod tests {
#[xmlserde(name = b"f", ty = "child", vec_size = 10)]
pub f: Vec<Child>,
#[xmlserde(name = b"cnt", ty = "attr", default = "default_zero")]
pub cnt: u32,
pub _cnt: u32,
}
let xml = r#"<root cnt="2">
<f age="15">Tom</f>
Expand Down Expand Up @@ -701,7 +701,7 @@ mod tests {
pub name: String,
}
let xml = r#"<pet name="Chaplin" age="1"/>"#;
let _ = xml_deserialize_from_str::<Pet>(&xml);
let _ = xml_deserialize_from_str::<Pet>(&xml).unwrap();
}

#[test]
Expand All @@ -713,7 +713,7 @@ mod tests {
pub name: String,
}
let xml = r#"<pet name="Chaplin" age="1"/>"#;
let _ = xml_deserialize_from_str::<Pet>(&xml);
let _ = xml_deserialize_from_str::<Pet>(&xml).unwrap();
}

#[test]
Expand All @@ -727,7 +727,7 @@ mod tests {
pub name: String,
}
let xml = r#"<pet name="Chaplin"><weight/></pet>"#;
let _ = xml_deserialize_from_str::<Pet>(&xml);
let _ = xml_deserialize_from_str::<Pet>(&xml).unwrap();
}

#[test]
Expand All @@ -739,6 +739,36 @@ mod tests {
pub name: String,
}
let xml = r#"<pet name="Chaplin"><weight/></pet>"#;
let _ = xml_deserialize_from_str::<Pet>(&xml);
let _ = xml_deserialize_from_str::<Pet>(&xml).unwrap();
}

// https://github.com/ImJeremyHe/xmlserde/issues/52
#[test]
fn test_issue_52() {
#[derive(XmlSerialize)]
#[xmlserde(root = b"root")]
struct Wrapper<T: XmlSerialize> {
#[xmlserde(name = b"header", ty = "attr")]
header: String,
#[xmlserde(ty = "untag")]
body: T,
}

#[derive(XmlSerialize)]
struct Foo {
#[xmlserde(name = b"Bar", ty = "child")]
bar: Bar,
}

#[derive(XmlSerialize)]
struct Bar {}

let wrapper = Wrapper {
header: "".to_string(),
body: Foo { bar: Bar {} },
};

let r = xml_serialize(wrapper);
assert_eq!(r, r#"<root header=""><Bar/></root>"#);
}
}

0 comments on commit 03ab237

Please sign in to comment.