Default namespace working version
This commit is contained in:
parent
99a7d561e0
commit
1d9081b07a
|
@ -2,15 +2,50 @@ extern crate proc_macro;
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
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<String> {
|
||||||
|
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<NestedMeta> {
|
||||||
|
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 {
|
pub fn to_xml(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as syn::DeriveInput);
|
let ast = parse_macro_input!(input as syn::DeriveInput);
|
||||||
|
|
||||||
let ident = &ast.ident;
|
let ident = &ast.ident;
|
||||||
let root_name = ident.to_string();
|
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 =
|
let mut output: proc_macro2::TokenStream =
|
||||||
TokenStream::from(quote!("<".to_owned() + #root_name + ">")).into();
|
TokenStream::from(quote!("<".to_owned() + #header + ">")).into();
|
||||||
|
|
||||||
match &ast.data {
|
match &ast.data {
|
||||||
syn::Data::Struct(ref 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 {
|
pub fn from_xml(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as syn::ItemStruct);
|
let ast = parse_macro_input!(input as syn::ItemStruct);
|
||||||
let ident = &ast.ident;
|
let ident = &ast.ident;
|
||||||
|
|
|
@ -4,6 +4,7 @@ use instant_xml::{FromXml, ToXml};
|
||||||
struct Unit;
|
struct Unit;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, ToXml)]
|
#[derive(Debug, Eq, PartialEq, ToXml)]
|
||||||
|
#[xml(namespace("URI"))]
|
||||||
struct StructWithNamedFields {
|
struct StructWithNamedFields {
|
||||||
flag: bool,
|
flag: bool,
|
||||||
string: String,
|
string: String,
|
||||||
|
@ -26,6 +27,6 @@ fn struct_with_named_fields() {
|
||||||
}
|
}
|
||||||
.to_xml()
|
.to_xml()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"<StructWithNamedFields><flag>true</flag><string>test</string><number>1</number></StructWithNamedFields>"
|
"<StructWithNamedFields xmlns=\"URI\"><flag>true</flag><string>test</string><number>1</number></StructWithNamedFields>"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue