Serialize empty elements more efficiently
This commit is contained in:
parent
89832babe9
commit
12402fb381
|
@ -177,26 +177,31 @@ fn serialize_struct(
|
||||||
data: &syn::DataStruct,
|
data: &syn::DataStruct,
|
||||||
meta: ContainerMeta,
|
meta: ContainerMeta,
|
||||||
) -> proc_macro2::TokenStream {
|
) -> proc_macro2::TokenStream {
|
||||||
|
let tag = meta.tag();
|
||||||
let mut body = TokenStream::new();
|
let mut body = TokenStream::new();
|
||||||
let mut attributes = TokenStream::new();
|
let mut attributes = TokenStream::new();
|
||||||
|
|
||||||
match &data.fields {
|
match &data.fields {
|
||||||
syn::Fields::Named(fields) => {
|
syn::Fields::Named(fields) => {
|
||||||
|
body.extend(quote!(serializer.end_start()?;));
|
||||||
for field in &fields.named {
|
for field in &fields.named {
|
||||||
if let Err(err) = named_field(field, &mut body, &mut attributes, &meta) {
|
if let Err(err) = named_field(field, &mut body, &mut attributes, &meta) {
|
||||||
return err.to_compile_error();
|
return err.to_compile_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
body.extend(quote!(serializer.write_close(prefix, #tag)?;));
|
||||||
}
|
}
|
||||||
syn::Fields::Unnamed(fields) => {
|
syn::Fields::Unnamed(fields) => {
|
||||||
|
body.extend(quote!(serializer.end_start()?;));
|
||||||
for (index, field) in fields.unnamed.iter().enumerate() {
|
for (index, field) in fields.unnamed.iter().enumerate() {
|
||||||
if let Err(err) = unnamed_field(field, index, &mut body) {
|
if let Err(err) = unnamed_field(field, index, &mut body) {
|
||||||
return err.to_compile_error();
|
return err.to_compile_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
body.extend(quote!(serializer.write_close(prefix, #tag)?;));
|
||||||
|
}
|
||||||
|
syn::Fields::Unit => body.extend(quote!(serializer.end_empty()?;)),
|
||||||
}
|
}
|
||||||
syn::Fields::Unit => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
let default_namespace = meta.default_namespace();
|
let default_namespace = meta.default_namespace();
|
||||||
let cx_len = meta.ns.prefixes.len();
|
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 (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
let tag = meta.tag();
|
let tag = meta.tag();
|
||||||
let ident = &input.ident;
|
let ident = &input.ident;
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
impl #impl_generics ToXml for #ident #ty_generics #where_clause {
|
impl #impl_generics ToXml for #ident #ty_generics #where_clause {
|
||||||
fn serialize<W: ::core::fmt::Write + ?::core::marker::Sized>(
|
fn serialize<W: ::core::fmt::Write + ?::core::marker::Sized>(
|
||||||
|
@ -239,14 +243,9 @@ fn serialize_struct(
|
||||||
|
|
||||||
// Finalize start element
|
// Finalize start element
|
||||||
#attributes
|
#attributes
|
||||||
serializer.end_start()?;
|
|
||||||
|
|
||||||
#body
|
#body
|
||||||
|
|
||||||
// Close tag
|
|
||||||
serializer.write_close(prefix, #tag)?;
|
|
||||||
serializer.pop(old);
|
serializer.pop(old);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,16 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
|
||||||
Ok(())
|
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> {
|
pub fn write_close(&mut self, prefix: Option<&str>, name: &str) -> Result<(), Error> {
|
||||||
if self.state != State::Element {
|
if self.state != State::Element {
|
||||||
return Err(Error::UnexpectedState("invalid state for close element"));
|
return Err(Error::UnexpectedState("invalid state for close element"));
|
||||||
|
|
|
@ -7,6 +7,5 @@ struct Unit;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unit() {
|
fn unit() {
|
||||||
assert_eq!(to_string(&Unit).unwrap(), "<Unit></Unit>");
|
assert_eq!(to_string(&Unit).unwrap(), "<Unit />");
|
||||||
//assert_eq!(Unit::from_xml("<Unit/>").unwrap(), Unit);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct Foo;
|
||||||
#[test]
|
#[test]
|
||||||
fn string_element() {
|
fn string_element() {
|
||||||
let v = StringElement("f42".to_owned(), Foo);
|
let v = StringElement("f42".to_owned(), Foo);
|
||||||
let xml = r#"<StringElement>f42<Foo></Foo></StringElement>"#;
|
let xml = r#"<StringElement>f42<Foo /></StringElement>"#;
|
||||||
assert_eq!(xml, to_string(&v).unwrap());
|
assert_eq!(xml, to_string(&v).unwrap());
|
||||||
assert_eq!(v, from_str(xml).unwrap());
|
assert_eq!(v, from_str(xml).unwrap());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue