diff --git a/instant-xml-macros/src/ser.rs b/instant-xml-macros/src/ser.rs index bb26789..87f1a61 100644 --- a/instant-xml-macros/src/ser.rs +++ b/instant-xml-macros/src/ser.rs @@ -177,26 +177,31 @@ fn serialize_struct( data: &syn::DataStruct, meta: ContainerMeta, ) -> proc_macro2::TokenStream { + let tag = meta.tag(); let mut body = TokenStream::new(); let mut attributes = TokenStream::new(); match &data.fields { syn::Fields::Named(fields) => { + body.extend(quote!(serializer.end_start()?;)); for field in &fields.named { if let Err(err) = named_field(field, &mut body, &mut attributes, &meta) { return err.to_compile_error(); } } + body.extend(quote!(serializer.write_close(prefix, #tag)?;)); } syn::Fields::Unnamed(fields) => { + body.extend(quote!(serializer.end_start()?;)); for (index, field) in fields.unnamed.iter().enumerate() { if let Err(err) = unnamed_field(field, index, &mut body) { return err.to_compile_error(); } } + body.extend(quote!(serializer.write_close(prefix, #tag)?;)); } - syn::Fields::Unit => {} - }; + syn::Fields::Unit => body.extend(quote!(serializer.end_empty()?;)), + } let default_namespace = meta.default_namespace(); let cx_len = meta.ns.prefixes.len(); @@ -221,7 +226,6 @@ fn serialize_struct( let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let tag = meta.tag(); let ident = &input.ident; - quote!( impl #impl_generics ToXml for #ident #ty_generics #where_clause { fn serialize( @@ -239,14 +243,9 @@ fn serialize_struct( // Finalize start element #attributes - serializer.end_start()?; - #body - // Close tag - serializer.write_close(prefix, #tag)?; serializer.pop(old); - Ok(()) } diff --git a/instant-xml/src/ser.rs b/instant-xml/src/ser.rs index 1172b53..18d1e74 100644 --- a/instant-xml/src/ser.rs +++ b/instant-xml/src/ser.rs @@ -111,6 +111,16 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> { Ok(()) } + pub fn end_empty(&mut self) -> Result<(), Error> { + if self.state != State::Attribute { + return Err(Error::UnexpectedState("invalid state for element end")); + } + + self.output.write_str(" />")?; + self.state = State::Element; + Ok(()) + } + pub fn write_close(&mut self, prefix: Option<&str>, name: &str) -> Result<(), Error> { if self.state != State::Element { return Err(Error::UnexpectedState("invalid state for close element")); diff --git a/instant-xml/tests/ser-unit.rs b/instant-xml/tests/ser-unit.rs index 15c35b1..5ac8408 100644 --- a/instant-xml/tests/ser-unit.rs +++ b/instant-xml/tests/ser-unit.rs @@ -7,6 +7,5 @@ struct Unit; #[test] fn unit() { - assert_eq!(to_string(&Unit).unwrap(), ""); - //assert_eq!(Unit::from_xml("").unwrap(), Unit); + assert_eq!(to_string(&Unit).unwrap(), ""); } diff --git a/instant-xml/tests/unnamed.rs b/instant-xml/tests/unnamed.rs index b7a5ea4..6e3782e 100644 --- a/instant-xml/tests/unnamed.rs +++ b/instant-xml/tests/unnamed.rs @@ -33,7 +33,7 @@ struct Foo; #[test] fn string_element() { let v = StringElement("f42".to_owned(), Foo); - let xml = r#"f42"#; + let xml = r#"f42"#; assert_eq!(xml, to_string(&v).unwrap()); assert_eq!(v, from_str(xml).unwrap()); }