diff --git a/yaserde/src/lib.rs b/yaserde/src/lib.rs index bc27947..6eedc66 100644 --- a/yaserde/src/lib.rs +++ b/yaserde/src/lib.rs @@ -144,7 +144,7 @@ mod testing { macro_rules! test_for_type { ($type:ty, $value:expr, $content:expr) => {{ #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "data")] + #[yaserde(rename = "data")] pub struct Data { item: $type, } @@ -166,7 +166,7 @@ mod testing { macro_rules! test_for_attribute_type { ($type: ty, $value: expr, $content: expr) => {{ #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "data")] + #[yaserde(rename = "data")] pub struct Data { #[yaserde(attribute)] item: $type, diff --git a/yaserde/tests/default.rs b/yaserde/tests/default.rs index 38fb151..c4ba308 100644 --- a/yaserde/tests/default.rs +++ b/yaserde/tests/default.rs @@ -13,7 +13,7 @@ fn default_field_string() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(default = "default_string")] background: String, @@ -42,7 +42,7 @@ fn default_field_boolean() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(default = "default_boolean")] background: bool, @@ -66,7 +66,7 @@ fn default_field_number() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(default = "default_number")] background: u8, @@ -90,7 +90,7 @@ fn default_attribute_string() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute, default = "default_string")] background: String, diff --git a/yaserde/tests/enum.rs b/yaserde/tests/enum.rs index ab96c42..cca4edf 100644 --- a/yaserde/tests/enum.rs +++ b/yaserde/tests/enum.rs @@ -9,13 +9,13 @@ use yaserde::{YaDeserialize, YaSerialize}; #[test] fn basic_enum() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { color: Color, } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "color")] + #[yaserde(rename = "color")] pub enum Color { White, Black, @@ -124,14 +124,14 @@ fn basic_enum() { #[test] fn attribute_enum() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute)] color: Color, } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "color")] + #[yaserde(rename = "color")] pub enum Color { #[yaserde(rename = "pink")] Pink, @@ -153,7 +153,7 @@ fn attribute_enum() { #[test] fn unnamed_enum() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { color: Enum, } diff --git a/yaserde/tests/namespace.rs b/yaserde/tests/namespace.rs index 4025e90..dd53c9e 100644 --- a/yaserde/tests/namespace.rs +++ b/yaserde/tests/namespace.rs @@ -10,7 +10,7 @@ use yaserde::{YaDeserialize, YaSerialize}; fn struct_simple_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -41,7 +41,7 @@ fn struct_simple_namespace() { fn struct_multiple_namespaces() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain", namespace = "ns2: http://www.sample.com/ns/domain_2" @@ -73,7 +73,7 @@ fn struct_multiple_namespaces() { fn struct_partial_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -103,7 +103,7 @@ fn struct_partial_namespace() { fn struct_sub_namespace_definition() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain", namespace = "ns2: http://www.sample.com/ns/domain_2" @@ -206,7 +206,7 @@ fn struct_namespace_nested_defined_at_root() { fn struct_attribute_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", namespace = "ns1: http://www.sample.com/ns/domain1", namespace = "ns2: http://www.sample.com/ns/domain2" )] @@ -236,7 +236,7 @@ fn struct_attribute_namespace() { fn struct_implicit_default_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "tt", + rename = "tt", namespace = "http://www.w3.org/ns/ttml", namespace = "ttm: http://www.w3.org/ns/ttml#metadata" )] @@ -258,7 +258,7 @@ fn struct_implicit_default_namespace() { fn struct_explicit_default_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "tt", + rename = "tt", default_namespace = "ttml", namespace = "ttml: http://www.w3.org/ns/ttml", namespace = "ttm: http://www.w3.org/ns/ttml#metadata" @@ -281,7 +281,7 @@ fn struct_explicit_default_namespace() { fn struct_default_namespace_via_attribute_with_prefix() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "tt", + rename = "tt", prefix = "TTML", default_namespace = "TTML", namespace = "TTML: http://www.w3.org/ns/ttml", @@ -305,7 +305,7 @@ fn struct_default_namespace_via_attribute_with_prefix() { fn enum_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -335,7 +335,7 @@ fn enum_namespace() { fn enum_multi_namespaces() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", namespace = "ns1: http://www.sample.com/ns/domain1", namespace = "ns2: http://www.sample.com/ns/domain2" )] @@ -376,7 +376,7 @@ fn enum_multi_namespaces() { fn enum_attribute_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -415,7 +415,7 @@ fn enum_attribute_namespace() { fn struct_bad_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain", namespace = "ns2: http://www.sample.com/ns/domain_2" diff --git a/yaserde/tests/serializer.rs b/yaserde/tests/serializer.rs index 2814f81..01b7921 100644 --- a/yaserde/tests/serializer.rs +++ b/yaserde/tests/serializer.rs @@ -9,7 +9,7 @@ use yaserde::YaSerialize; #[test] fn ser_basic() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { item: String, } @@ -25,7 +25,7 @@ fn ser_basic() { #[test] fn ser_list_of_items() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { items: Vec, } @@ -38,13 +38,13 @@ fn ser_list_of_items() { serialize_and_validate!(model, content); #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStructOfStruct { items: Vec, } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "items")] + #[yaserde(rename = "items")] pub struct SubStruct { field: String, } @@ -68,7 +68,7 @@ fn ser_list_of_items() { #[test] fn ser_attributes() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute)] item: String, @@ -76,7 +76,7 @@ fn ser_attributes() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "sub")] + #[yaserde(rename = "sub")] pub struct SubStruct { #[yaserde(attribute)] subitem: String, @@ -167,7 +167,7 @@ fn ser_attributes_complex() { #[test] fn ser_rename() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute, rename = "Item")] item: String, @@ -178,7 +178,7 @@ fn ser_rename() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "sub")] + #[yaserde(rename = "sub")] pub struct SubStruct { #[yaserde(attribute, rename = "sub_item")] subitem: String, @@ -214,7 +214,7 @@ fn ser_rename() { #[test] fn ser_text_content_with_attributes() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute, rename = "Item")] item: String, @@ -223,7 +223,7 @@ fn ser_text_content_with_attributes() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "sub")] + #[yaserde(rename = "sub")] pub struct SubStruct { #[yaserde(attribute, rename = "sub_item")] subitem: String, @@ -263,7 +263,7 @@ fn ser_text_content_with_attributes() { #[test] fn ser_name_issue_21() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { name: String, } diff --git a/yaserde/tests/skip_if.rs b/yaserde/tests/skip_if.rs index ed45cb2..e7c853e 100644 --- a/yaserde/tests/skip_if.rs +++ b/yaserde/tests/skip_if.rs @@ -13,7 +13,7 @@ fn skip_serializing_if_for_struct() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde( skip_serializing_if = "check_string_function", diff --git a/yaserde_derive/src/common/attribute.rs b/yaserde_derive/src/common/attribute.rs index 6504dad..45b1138 100644 --- a/yaserde_derive/src/common/attribute.rs +++ b/yaserde_derive/src/common/attribute.rs @@ -1,6 +1,4 @@ -use proc_macro2::token_stream::IntoIter; -use proc_macro2::Delimiter; -use proc_macro2::TokenTree; +use proc_macro2::{token_stream::IntoIter, Delimiter, TokenStream, TokenTree}; use std::collections::BTreeMap; use syn::Attribute; @@ -12,7 +10,6 @@ pub struct YaSerdeAttribute { pub flatten: bool, pub namespaces: BTreeMap, pub prefix: Option, - pub root: Option, pub rename: Option, pub skip_serializing_if: Option, pub text: bool, @@ -41,7 +38,6 @@ impl YaSerdeAttribute { let mut namespaces = BTreeMap::new(); let mut prefix = None; let mut rename = None; - let mut root = None; let mut skip_serializing_if = None; let mut text = false; @@ -84,9 +80,6 @@ impl YaSerdeAttribute { "rename" => { rename = get_value(&mut attr_iter); } - "root" => { - root = get_value(&mut attr_iter); - } "skip_serializing_if" => { skip_serializing_if = get_value(&mut attr_iter); } @@ -110,11 +103,51 @@ impl YaSerdeAttribute { namespaces, prefix, rename, - root, skip_serializing_if, text, } } + + pub fn get_namespace_matching( + &self, + prefix: &Option, + element_namespace: TokenStream, + element_name: TokenStream, + take_root_prefix: bool + ) -> TokenStream { + let configured_prefix = + if take_root_prefix { + self.prefix.clone() + } else { + prefix.clone() + }; + + let namespaces_matches : TokenStream = + self + .namespaces + .iter() + .map(|(prefix, namespace)| { + if configured_prefix == Some(prefix.to_string()) { + Some(quote!(#namespace => {})) + } else { + None + } + }) + .filter_map(|x| x) + .collect(); + + quote!( + if let Some(namespace) = #element_namespace { + match namespace.as_str() { + #namespaces_matches + bad_namespace => { + let msg = format!("bad namespace for {}, found {}", #element_name, bad_namespace); + return Err(msg); + } + } + } + ) + } } #[test] @@ -130,7 +163,6 @@ fn parse_empty_attributes() { flatten: false, namespaces: BTreeMap::new(), prefix: None, - root: None, rename: None, skip_serializing_if: None, text: false, @@ -180,7 +212,6 @@ fn parse_attributes() { flatten: false, namespaces: BTreeMap::new(), prefix: None, - root: None, rename: None, skip_serializing_if: None, text: false, @@ -205,7 +236,6 @@ fn parse_attributes_with_values() { arguments: PathArguments::None, }); - // #[()] let attributes = vec![Attribute { pound_token: Pound { spans: [Span::call_site()], @@ -234,7 +264,6 @@ fn parse_attributes_with_values() { flatten: true, namespaces, prefix: None, - root: None, rename: None, skip_serializing_if: None, text: false, diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index e2faa0a..241bf2c 100644 --- a/yaserde_derive/src/common/field.rs +++ b/yaserde_derive/src/common/field.rs @@ -118,19 +118,13 @@ impl YaSerdeField { .map(|skip_serializing_if| Ident::new(&skip_serializing_if, self.get_span())) } - pub fn get_namespace_matching(&self, root_attributes: &YaSerdeAttribute) -> TokenStream { - root_attributes - .namespaces - .iter() - .map(|(prefix, namespace)| { - if self.attributes.prefix == Some(prefix.to_string()) { - Some(quote!(#namespace => {})) - } else { - None - } - }) - .filter_map(|x| x) - .collect() + pub fn get_namespace_matching( + &self, + root_attributes: &YaSerdeAttribute, + element_namespace: TokenStream, + element_name: TokenStream, + ) -> TokenStream { + root_attributes.get_namespace_matching(&self.attributes.prefix, element_namespace, element_name, false) } pub fn ser_wrap_default_attribute( @@ -184,37 +178,6 @@ pub enum Field { } impl Field { - pub fn is_attribute(token_field: &syn::Field) -> bool { - YaSerdeAttribute::parse(&token_field.attrs).attribute - } - - pub fn is_text_content(token_field: &syn::Field) -> bool { - YaSerdeAttribute::parse(&token_field.attrs).text - } - - pub fn label(token_field: &syn::Field) -> Option { - token_field.ident.clone() - } - - pub fn renamed_label(token_field: &syn::Field, root_attributes: &YaSerdeAttribute) -> String { - let attributes = YaSerdeAttribute::parse(&token_field.attrs); - - let prefix = if root_attributes.default_namespace == attributes.prefix { - "".to_string() - } else { - attributes - .prefix - .clone() - .map_or("".to_string(), |prefix| prefix + ":") - }; - - let label = attributes - .rename - .unwrap_or_else(|| token_field.ident.as_ref().unwrap().to_string()); - - format!("{}{}", prefix, label) - } - pub fn get_simple_type_visitor(&self) -> TokenStream { let ident = format_ident!("visit_{}", self.to_string()); quote! {#ident} diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 0bc283f..0a4bffd 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -9,18 +9,7 @@ pub fn parse( root: &str, root_attributes: &YaSerdeAttribute, ) -> TokenStream { - let namespaces_matches: TokenStream = root_attributes - .namespaces - .iter() - .map(|(prefix, namespace)| { - if root_attributes.prefix.as_ref() == Some(prefix) { - Some(quote!(#namespace => {})) - } else { - None - } - }) - .filter_map(|x| x) - .collect(); + let namespaces_matching = root_attributes.get_namespace_matching(&None, quote!(struct_namespace), quote!(named_element), true); let variables: TokenStream = data_struct .fields @@ -330,15 +319,7 @@ pub fn parse( debug!("Struct: start to parse {:?}", named_element); if reader.depth() == 0 { - if let Some(ref namespace) = struct_namespace { - match namespace.as_str() { - #namespaces_matches - bad_ns => { - let msg = format!("bad namespace for {}, found {}", named_element, bad_ns); - return Err(msg); - } - } - } + #namespaces_matching } #variables @@ -419,21 +400,13 @@ fn build_call_visitor( let label_name = field.renamed_label_without_namespace(); let visitor_label = build_visitor_ident(&label_name, field.get_span(), None); - let namespaces_matches = field.get_namespace_matching(root_attributes); + let namespaces_matching = field.get_namespace_matching(root_attributes, quote!(name.namespace.as_ref()), quote!(name.local_name.as_str())); Some(quote! { #label_name => { let visitor = #visitor_label{}; - if let Some(namespace) = name.namespace.as_ref() { - match namespace.as_str() { - #namespaces_matches - bad_ns => { - let msg = format!("bad field namespace for {}, found {}", name.local_name.as_str(), bad_ns); - return Err(msg); - } - } - } + #namespaces_matching let result = reader.read_inner_value::<#field_type, _>(|reader| { if let Ok(XmlEvent::Characters(s)) = reader.peek() { diff --git a/yaserde_derive/src/de/mod.rs b/yaserde_derive/src/de/mod.rs index ec9ff56..a4c4355 100644 --- a/yaserde_derive/src/de/mod.rs +++ b/yaserde_derive/src/de/mod.rs @@ -12,14 +12,14 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result { - expand_struct::parse(data_struct, name, &root, &root_attrs) + expand_struct::parse(data_struct, name, &root_name, &root_attributes) } - syn::Data::Enum(ref data_enum) => expand_enum::parse(data_enum, name, &root, &root_attrs), + syn::Data::Enum(ref data_enum) => expand_enum::parse(data_enum, name, &root_name, &root_attributes), syn::Data::Union(ref _data_union) => unimplemented!(), }; diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs index c294514..23d8353 100644 --- a/yaserde_derive/src/ser/mod.rs +++ b/yaserde_derive/src/ser/mod.rs @@ -15,25 +15,30 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result { - expand_struct::serialize(data_struct, name, &root, &root_attrs) + expand_struct::serialize(data_struct, name, &root_name, &root_attributes) + } + syn::Data::Enum(ref data_enum) => { + expand_enum::serialize(data_enum, name, &root_name, &root_attributes) } - syn::Data::Enum(ref data_enum) => expand_enum::serialize(data_enum, name, &root, &root_attrs), syn::Data::Union(ref _data_union) => unimplemented!(), };