From 1d9081b07a5b11436625511fc663c8ed23f231bd Mon Sep 17 00:00:00 2001 From: Bartlomiej Choinski Date: Thu, 9 Jun 2022 12:44:46 +0200 Subject: [PATCH] Default namespace working version --- instant-xml-macros/src/lib.rs | 43 +++++++++++++++++++++++++++++++---- instant-xml/tests/all.rs | 3 ++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/instant-xml-macros/src/lib.rs b/instant-xml-macros/src/lib.rs index adc333f..b2ec26e 100644 --- a/instant-xml-macros/src/lib.rs +++ b/instant-xml-macros/src/lib.rs @@ -2,15 +2,50 @@ extern crate proc_macro; use proc_macro::TokenStream; use quote::quote; -use syn::parse_macro_input; +use syn::{parse_macro_input, DeriveInput, Lit, Meta, NestedMeta}; -#[proc_macro_derive(ToXml)] +fn retrieve_default_namespace(input: &DeriveInput) -> Option { + if let NestedMeta::Meta(Meta::List(list)) = get_meta_items(&input.attrs).first()? { + if list.path.get_ident()? == "namespace" { + if let NestedMeta::Lit(Lit::Str(v)) = list.nested.first()? { + return Some(v.value()); + } + } + } + None +} + +const XML: &str = "xml"; + +pub(crate) fn get_meta_items(attrs: &[syn::Attribute]) -> Vec { + let mut out = Vec::new(); + for attr in attrs { + if !attr.path.is_ident(XML) { + continue; + } + + match attr.parse_meta() { + Ok(Meta::List(meta)) => out.extend(meta.nested.into_iter()), + Ok(_) => todo!(), + _ => todo!(), + } + } + out +} + +#[proc_macro_derive(ToXml, attributes(xml))] pub fn to_xml(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as syn::DeriveInput); + let ident = &ast.ident; let root_name = ident.to_string(); + let mut header: String = root_name.to_string(); + if let Some(v) = retrieve_default_namespace(&ast) { + header += format!(" xmlns=\"{}\"", v).as_str(); + }; + let mut output: proc_macro2::TokenStream = - TokenStream::from(quote!("<".to_owned() + #root_name + ">")).into(); + TokenStream::from(quote!("<".to_owned() + #header + ">")).into(); match &ast.data { syn::Data::Struct(ref data) => { @@ -44,7 +79,7 @@ pub fn to_xml(input: TokenStream) -> TokenStream { )) } -#[proc_macro_derive(FromXml)] +#[proc_macro_derive(FromXml, attributes(xml))] pub fn from_xml(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as syn::ItemStruct); let ident = &ast.ident; diff --git a/instant-xml/tests/all.rs b/instant-xml/tests/all.rs index d552a19..5ce382f 100644 --- a/instant-xml/tests/all.rs +++ b/instant-xml/tests/all.rs @@ -4,6 +4,7 @@ use instant_xml::{FromXml, ToXml}; struct Unit; #[derive(Debug, Eq, PartialEq, ToXml)] +#[xml(namespace("URI"))] struct StructWithNamedFields { flag: bool, string: String, @@ -26,6 +27,6 @@ fn struct_with_named_fields() { } .to_xml() .unwrap(), - "truetest1" + "truetest1" ); }