From dc7980612884f4443604f8f2157d78931ac85b8f Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Mon, 24 Feb 2020 14:47:18 +0100 Subject: [PATCH] add default_namespace attribute issue #45 --- yaserde/tests/se_namespace.rs | 21 +++++++++ yaserde_derive/src/attribute.rs | 58 ++++++++++++++----------- yaserde_derive/src/ser/expand_enum.rs | 8 ++++ yaserde_derive/src/ser/expand_struct.rs | 8 ++++ yaserde_derive/src/ser/mod.rs | 20 ++++++--- 5 files changed, 84 insertions(+), 31 deletions(-) diff --git a/yaserde/tests/se_namespace.rs b/yaserde/tests/se_namespace.rs index 201f11e..981307c 100644 --- a/yaserde/tests/se_namespace.rs +++ b/yaserde/tests/se_namespace.rs @@ -161,6 +161,27 @@ fn ser_struct_default_namespace() { convert_and_validate!(model, content); } +#[test] +fn ser_struct_default_namespace_via_attribute() { + #[derive(YaSerialize, PartialEq, Debug)] + #[yaserde( + root = "tt", + default_namespace = "ttml", + namespace = "ttml: http://www.w3.org/ns/ttml", + namespace = "ttm: http://www.w3.org/ns/ttml#metadata" + )] + pub struct XmlStruct { + item: String, + } + + let model = XmlStruct { + item: "something".to_string(), + }; + + let content = "something"; + convert_and_validate!(model, content); +} + #[test] fn de_struct_namespace_nested() { #[derive(YaSerialize, Default, PartialEq, Debug)] diff --git a/yaserde_derive/src/attribute.rs b/yaserde_derive/src/attribute.rs index 3caa3ef..19c6831 100644 --- a/yaserde_derive/src/attribute.rs +++ b/yaserde_derive/src/attribute.rs @@ -6,14 +6,15 @@ use syn::Attribute; #[derive(Debug, PartialEq, Clone)] pub struct YaSerdeAttribute { - pub root: Option, - pub rename: Option, - pub prefix: Option, + pub attribute: bool, pub default: Option, + pub default_namespace: Option, + pub flatten: bool, pub namespaces: BTreeMap, - pub attribute: bool, + pub prefix: Option, + pub root: Option, + pub rename: Option, pub text: bool, - pub flatten: bool, } fn get_value(iter: &mut IntoIter) -> Option { @@ -33,13 +34,14 @@ fn get_value(iter: &mut IntoIter) -> Option { impl YaSerdeAttribute { pub fn parse(attrs: &[Attribute]) -> YaSerdeAttribute { let mut attribute = false; + let mut flatten = false; + let mut default = None; + let mut default_namespace = None; let mut namespaces = BTreeMap::new(); let mut prefix = None; let mut rename = None; let mut root = None; - let mut default = None; let mut text = false; - let mut flatten = false; for attr in attrs.iter() { let mut attr_iter = attr.clone().tokens.into_iter(); @@ -54,6 +56,15 @@ impl YaSerdeAttribute { "attribute" => { attribute = true; } + "default" => { + default = get_value(&mut attr_iter); + } + "default_namespace" => { + default_namespace = get_value(&mut attr_iter); + } + "flatten" => { + flatten = true; + } "namespace" => { if let Some(namespace) = get_value(&mut attr_iter) { let splitted: Vec<&str> = namespace.split(": ").collect(); @@ -74,15 +85,9 @@ impl YaSerdeAttribute { "root" => { root = get_value(&mut attr_iter); } - "default" => { - default = get_value(&mut attr_iter); - } "text" => { text = true; } - "flatten" => { - flatten = true; - } _ => {} } } @@ -94,13 +99,14 @@ impl YaSerdeAttribute { YaSerdeAttribute { attribute, + default, + default_namespace, + flatten, namespaces, prefix, rename, root, - default, text, - flatten, } } } @@ -112,14 +118,15 @@ fn parse_empty_attributes() { assert_eq!( YaSerdeAttribute { - root: None, - rename: None, - prefix: None, + attribute: false, default: None, + default_namespace: None, + flatten: false, namespaces: BTreeMap::new(), - attribute: false, + prefix: None, + root: None, + rename: None, text: false, - flatten: false, }, attrs ); @@ -160,14 +167,15 @@ fn parse_attributes() { assert_eq!( YaSerdeAttribute { - root: None, - rename: None, - prefix: None, + attribute: true, default: None, + default_namespace: None, + flatten: false, namespaces: BTreeMap::new(), - attribute: true, + prefix: None, + root: None, + rename: None, text: false, - flatten: false, }, attrs ); diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index dadd224..713eba5 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -12,6 +12,7 @@ pub fn serialize( name: &Ident, root: &str, namespaces: &BTreeMap, + default_namespace: &Option, ) -> TokenStream { let write_enum_content: TokenStream = data_enum .variants @@ -212,6 +213,13 @@ pub fn serialize( let add_namespaces: TokenStream = namespaces .iter() .map(|(prefix, namespace)| { + if let Some(dn) = default_namespace { + if dn == prefix { + return Some(quote!( + .default_ns(#namespace) + )); + } + } Some(quote!( .ns(#prefix, #namespace) )) diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 44b872f..6b5b704 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -14,6 +14,7 @@ pub fn serialize( name: &Ident, root: &str, namespaces: &BTreeMap, + default_namespace: &Option, ) -> TokenStream { let build_attributes: TokenStream = data_struct .fields @@ -208,6 +209,13 @@ pub fn serialize( let add_namespaces: TokenStream = namespaces .iter() .map(|(prefix, namespace)| { + if let Some(dn) = default_namespace { + if dn == prefix { + return Some(quote!( + .default_ns(#namespace) + )); + } + } Some(quote!( .ns(#prefix, #namespace) )) diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs index ff8ecff..d801b61 100644 --- a/yaserde_derive/src/ser/mod.rs +++ b/yaserde_derive/src/ser/mod.rs @@ -22,12 +22,20 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result { - expand_struct::serialize(data_struct, name, &root, &root_attrs.namespaces) - } - syn::Data::Enum(ref data_enum) => { - expand_enum::serialize(data_enum, name, &root, &root_attrs.namespaces) - } + syn::Data::Struct(ref data_struct) => expand_struct::serialize( + data_struct, + name, + &root, + &root_attrs.namespaces, + &root_attrs.default_namespace, + ), + syn::Data::Enum(ref data_enum) => expand_enum::serialize( + data_enum, + name, + &root, + &root_attrs.namespaces, + &root_attrs.default_namespace, + ), syn::Data::Union(ref _data_union) => unimplemented!(), };