support de/ser-ialization with namespace

This commit is contained in:
Marc-Antoine Arnaud
2018-05-13 17:43:36 +02:00
parent 355565c84d
commit 07a258f8fc
10 changed files with 300 additions and 42 deletions

View File

@@ -2,12 +2,13 @@
use attribute::*;
use field_type::*;
use quote::Tokens;
use std::collections::BTreeMap;
use syn::Fields;
use syn::Ident;
use syn::DataEnum;
use proc_macro2::Span;
pub fn parse(data_enum: &DataEnum, name: &Ident, root: &String) -> Tokens {
pub fn parse(data_enum: &DataEnum, name: &Ident, root: &String, namespaces: &BTreeMap<String, String>) -> Tokens {
let variables : Tokens = data_enum.variants.iter().map(|ref variant|
{
match variant.fields {

View File

@@ -2,11 +2,33 @@
use attribute::*;
use field_type::*;
use quote::Tokens;
use std::collections::BTreeMap;
use syn::Ident;
use syn::DataStruct;
use proc_macro2::Span;
pub fn parse(data_struct: &DataStruct, name: &Ident, root: &String) -> Tokens {
pub fn parse(data_struct: &DataStruct, name: &Ident, root: &String, namespaces: &BTreeMap<String, String>) -> Tokens {
let validate_namespace : Tokens = namespaces.iter().map(|(ref prefix, ref namespace)| {
Some(quote!(
let mut found = false;
for (key, value) in namespace {
if #namespace == value {
found = true;
}
}
if !found {
return Err("bad namespace".to_string());
}
// println!("{}: {}", #prefix, #namespace);
))
})
.filter(|x| x.is_some())
.map(|x| x.unwrap())
.fold(Tokens::new(), |mut tokens, token| {tokens.append_all(token); tokens});
let variables: Tokens = data_struct.fields.iter().map(|ref field|
{
let label = field.ident;
@@ -353,7 +375,9 @@ pub fn parse(data_struct: &DataStruct, name: &Ident, root: &String) -> Tokens {
loop {
match reader.peek()?.to_owned() {
XmlEvent::StartElement{ref name, ref attributes, ..} => {
XmlEvent::StartElement{ref name, ref attributes, ref namespace} => {
#validate_namespace
match name.local_name.as_str() {
#call_visitors
named_element => {

View File

@@ -19,10 +19,10 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<quote::Tokens
let impl_block =
match data {
&syn::Data::Struct(ref data_struct) => {
expand_struct::parse(data_struct, &name, &root)
expand_struct::parse(data_struct, &name, &root, &root_attrs.namespaces)
},
&syn::Data::Enum(ref data_enum) => {
expand_enum::parse(data_enum, &name, &root)
expand_enum::parse(data_enum, &name, &root, &root_attrs.namespaces)
},
&syn::Data::Union(ref _data_union) => {
unimplemented!()