Use absolute paths in generated code

With this, the derives should work with most of the crates and types
the generated code refers to being aliased.

Notably, methods are still mostly invoked using regular method syntax
so those coming from trait could still be aliased by outside code.
This commit is contained in:
Jonas Platte 2020-12-02 17:11:36 +01:00
parent 52fb60ec8b
commit 12ddcdbc87
No known key found for this signature in database
GPG Key ID: 9D5B897BFF66575C
20 changed files with 256 additions and 234 deletions

View File

@ -3,9 +3,6 @@ extern crate yaserde;
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::{Read, Write};
use yaserde::{YaDeserialize, YaSerialize};
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();
} }
@ -128,8 +125,6 @@ fn module_inclusion() {
init(); init();
mod module { mod module {
use super::*;
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)]
#[yaserde(rename = "module")] #[yaserde(rename = "module")]
pub struct Module { pub struct Module {

View File

@ -4,9 +4,9 @@ extern crate yaserde;
extern crate yaserde_derive; extern crate yaserde_derive;
use log::debug; use log::debug;
use std::io::{Read, Write}; use std::io::Read;
use yaserde::de::from_str; use yaserde::de::from_str;
use yaserde::{YaDeserialize, YaSerialize}; use yaserde::YaDeserialize;
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();
@ -115,9 +115,6 @@ fn de_multiple_segments() {
init(); init();
mod other_mod { mod other_mod {
use std::io::Read;
use yaserde::YaDeserialize;
#[derive(YaDeserialize, PartialEq, Debug, Default)] #[derive(YaDeserialize, PartialEq, Debug, Default)]
pub struct Page { pub struct Page {
pub number: i32, pub number: i32,
@ -311,8 +308,6 @@ fn de_attributes_complex() {
init(); init();
mod other_mod { mod other_mod {
use super::*;
#[derive(YaDeserialize, PartialEq, Debug)] #[derive(YaDeserialize, PartialEq, Debug)]
pub enum AttrEnum { pub enum AttrEnum {
#[yaserde(rename = "variant 1")] #[yaserde(rename = "variant 1")]

View File

@ -3,9 +3,6 @@ extern crate yaserde;
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::{Read, Write};
use yaserde::{YaDeserialize, YaSerialize};
#[test] #[test]
fn basic_enum() { fn basic_enum() {
#[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]

View File

@ -1,9 +1,7 @@
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::Read;
use yaserde::de::from_str; use yaserde::de::from_str;
use yaserde::YaDeserialize;
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();

View File

@ -3,10 +3,6 @@ extern crate yaserde;
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::{Read, Write};
use yaserde::{YaDeserialize, YaSerialize};
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();
} }

View File

@ -3,9 +3,6 @@ extern crate yaserde;
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::{Read, Write};
use yaserde::{YaDeserialize, YaSerialize};
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();
} }

View File

@ -3,9 +3,6 @@ extern crate yaserde;
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::{Read, Write};
use yaserde::{YaDeserialize, YaSerialize};
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();
} }

View File

@ -177,8 +177,6 @@ fn ser_attributes() {
#[test] #[test]
fn ser_attributes_complex() { fn ser_attributes_complex() {
mod other_mod { mod other_mod {
use super::*;
#[derive(YaSerialize, PartialEq, Debug)] #[derive(YaSerialize, PartialEq, Debug)]
pub enum AttrEnum { pub enum AttrEnum {
#[yaserde(rename = "variant 1")] #[yaserde(rename = "variant 1")]

View File

@ -3,9 +3,6 @@ extern crate yaserde;
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::Write;
use yaserde::YaSerialize;
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();
} }

View File

@ -3,9 +3,6 @@ extern crate yaserde;
#[macro_use] #[macro_use]
extern crate yaserde_derive; extern crate yaserde_derive;
use std::io::{Read, Write};
use yaserde::{YaDeserialize, YaSerialize};
fn init() { fn init() {
let _ = env_logger::builder().is_test(true).try_init(); let _ = env_logger::builder().is_test(true).try_init();
} }

View File

@ -155,7 +155,8 @@ impl YaSerdeAttribute {
match namespace.as_str() { match namespace.as_str() {
#namespaces_matches #namespaces_matches
bad_namespace => { bad_namespace => {
let msg = format!("bad namespace for {}, found {}", #element_name, bad_namespace); let msg =
::std::format!("bad namespace for {}, found {}", #element_name, bad_namespace);
return Err(msg); return Err(msg);
} }
} }

View File

@ -256,18 +256,18 @@ impl From<&syn::PathSegment> for Field {
impl Into<proc_macro2::TokenStream> for Field { impl Into<proc_macro2::TokenStream> for Field {
fn into(self) -> proc_macro2::TokenStream { fn into(self) -> proc_macro2::TokenStream {
match self { match self {
Field::FieldString => quote! {std::string::String}, Field::FieldString => quote! { ::std::string::String },
Field::FieldBool => quote! {bool}, Field::FieldBool => quote! { ::std::primitive::bool },
Field::FieldI8 => quote! {i8}, Field::FieldI8 => quote! { ::std::primitive::i8 },
Field::FieldU8 => quote! {u8}, Field::FieldU8 => quote! { ::std::primitive::u8 },
Field::FieldI16 => quote! {i16}, Field::FieldI16 => quote! { ::std::primitive::i16 },
Field::FieldU16 => quote! {u16}, Field::FieldU16 => quote! { ::std::primitive::u16 },
Field::FieldI32 => quote! {i32}, Field::FieldI32 => quote! { ::std::primitive::i32 },
Field::FieldU32 => quote! {u32}, Field::FieldU32 => quote! { ::std::primitive::u32 },
Field::FieldI64 => quote! {i64}, Field::FieldI64 => quote! { ::std::primitive::i64 },
Field::FieldU64 => quote! {u64}, Field::FieldU64 => quote! { ::std::primitive::u64 },
Field::FieldF32 => quote! {f32}, Field::FieldF32 => quote! { ::std::primitive::f32 },
Field::FieldF64 => quote! {f64}, Field::FieldF64 => quote! { ::std::primitive::f64 },
_ => panic!("Not a simple type: {:?}", self), _ => panic!("Not a simple type: {:?}", self),
} }
} }

View File

@ -26,35 +26,31 @@ pub fn parse(
let flatten = root_attributes.flatten; let flatten = root_attributes.flatten;
quote! { quote! {
use xml::reader::XmlEvent; impl ::yaserde::YaDeserialize for #name {
use yaserde::Visitor;
#[allow(unknown_lints, unused_imports)]
use std::str::FromStr;
use log::{debug, trace};
impl YaDeserialize for #name {
#[allow(unused_variables)] #[allow(unused_variables)]
fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, std::string::String> { fn deserialize<R: ::std::io::Read>(
reader: &mut ::yaserde::de::Deserializer<R>,
) -> ::std::result::Result<Self, ::std::string::String> {
let (named_element, enum_namespace) = let (named_element, enum_namespace) =
if let XmlEvent::StartElement{name, ..} = reader.peek()?.to_owned() { if let ::xml::reader::XmlEvent::StartElement{ name, .. } = reader.peek()?.to_owned() {
(name.local_name.to_owned(), name.namespace.clone()) (name.local_name.to_owned(), name.namespace.clone())
} else { } else {
(std::string::String::from(#root), None) (::std::string::String::from(#root), ::std::option::Option::None)
}; };
let start_depth = reader.depth(); let start_depth = reader.depth();
debug!("Enum {} @ {}: start to parse {:?}", stringify!(#name), start_depth, named_element); ::log::debug!("Enum {} @ {}: start to parse {:?}", stringify!(#name), start_depth, named_element);
#namespaces_matching #namespaces_matching
#[allow(unused_assignments, unused_mut)] #[allow(unused_assignments, unused_mut)]
let mut enum_value = None; let mut enum_value = ::std::option::Option::None;
loop { loop {
let event = reader.peek()?.to_owned(); let event = reader.peek()?.to_owned();
trace!("Enum {} @ {}: matching {:?}", stringify!(#name), start_depth, event); ::log::trace!("Enum {} @ {}: matching {:?}", stringify!(#name), start_depth, event);
match event { match event {
XmlEvent::StartElement{ref name, ref attributes, ..} => { ::xml::reader::XmlEvent::StartElement { ref name, ref attributes, .. } => {
match name.local_name.as_str() { match name.local_name.as_str() {
#match_to_enum #match_to_enum
_named_element => { _named_element => {
@ -62,40 +58,42 @@ pub fn parse(
} }
} }
if let XmlEvent::Characters(content) = reader.peek()?.to_owned() { if let ::xml::reader::XmlEvent::Characters(content) = reader.peek()?.to_owned() {
match content.as_str() { match content.as_str() {
#match_to_enum #match_to_enum
_ => {} _ => {}
} }
} }
} }
XmlEvent::EndElement{ref name} => { ::xml::reader::XmlEvent::EndElement { ref name } => {
if name.local_name == named_element { if name.local_name == named_element {
break; break;
} }
let _root = reader.next_event(); let _root = reader.next_event();
} }
XmlEvent::Characters(ref text_content) => { ::xml::reader::XmlEvent::Characters(ref text_content) => {
let _root = reader.next_event(); let _root = reader.next_event();
} }
XmlEvent::EndDocument => { ::xml::reader::XmlEvent::EndDocument => {
if #flatten { if #flatten {
break; break;
} }
return Err(format!("End of document, missing some content ?")) return ::std::result::Result::Err(
::std::format!("End of document, missing some content ?"),
);
} }
event => { event => {
return Err(format!("unknown event {:?}", event)) return ::std::result::Result::Err(::std::format!("unknown event {:?}", event))
} }
} }
} }
debug!("Enum {} @ {}: success", stringify!(#name), start_depth); ::log::debug!("Enum {} @ {}: success", stringify!(#name), start_depth);
match enum_value { match enum_value {
Some(value) => Ok(value), ::std::option::Option::Some(value) => ::std::result::Result::Ok(value),
None => { ::std::option::Option::None => {
Ok(#name::default()) ::std::result::Result::Ok(<#name as ::std::default::Default>::default())
}, },
} }
} }
@ -114,7 +112,7 @@ fn parse_variant(variant: &syn::Variant, name: &Ident) -> Option<TokenStream> {
match variant.fields { match variant.fields {
Fields::Unit => Some(quote! { Fields::Unit => Some(quote! {
#xml_element_name => { #xml_element_name => {
enum_value = Some(#variant_name); enum_value = ::std::option::Option::Some(#variant_name);
} }
}), }),
Fields::Unnamed(ref fields) => { Fields::Unnamed(ref fields) => {
@ -159,10 +157,13 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
Some(quote! { Some(quote! {
#[allow(non_snake_case, non_camel_case_types)] #[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label; struct #visitor_label;
impl<'de> Visitor<'de> for #visitor_label { impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
type Value = #field_type; type Value = #field_type;
fn #visitor(self, v: &str) -> Result<Self::Value, std::string::String> { fn #visitor(
self,
v: &::std::primitive::str,
) -> ::std::result::Result<Self::Value, ::std::string::String> {
#fn_body #fn_body
} }
} }
@ -176,7 +177,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
make_visitor( make_visitor(
&visitor, &visitor,
&field_type, &field_type,
&quote! { Ok(#field_type::from_str(v).unwrap()) }, &quote! { ::std::result::Result::Ok(#field_type::from_str(v).unwrap()) },
) )
}; };
@ -193,7 +194,8 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
&quote! { #struct_name }, &quote! { #struct_name },
&quote! { &quote! {
let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">"; let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">";
let value : Result<#struct_name, std::string::String> = yaserde::de::from_str(&content); let value: ::std::result::Result<#struct_name, ::std::string::String> =
::yaserde::de::from_str(&content);
value value
}, },
) )
@ -231,18 +233,22 @@ fn build_unnamed_visitor_calls(
let visitor = #visitor_label{}; let visitor = #visitor_label{};
let result = reader.read_inner_value::<#field_type, _>(|reader| { let result = reader.read_inner_value::<#field_type, _>(|reader| {
if let XmlEvent::EndElement { .. } = *reader.peek()? { if let ::xml::reader::XmlEvent::EndElement { .. } = *reader.peek()? {
return visitor.#visitor(""); return visitor.#visitor("");
} }
if let Ok(XmlEvent::Characters(s)) = reader.next_event() { if let ::std::result::Result::Ok(::xml::reader::XmlEvent::Characters(s))
= reader.next_event()
{
visitor.#visitor(&s) visitor.#visitor(&s)
} else { } else {
Err(format!("unable to parse content for {}", #label_name)) ::std::result::Result::Err(
::std::format!("unable to parse content for {}", #label_name),
)
} }
}); });
if let Ok(value) = result { if let ::std::result::Result::Ok(value) = result {
#action #action
} }
}) })
@ -262,16 +268,24 @@ fn build_unnamed_visitor_calls(
}) })
}; };
let set_val = quote! { enum_value = Some(#variant_name(value)) }; let set_val = quote! {
let set_opt = quote! { enum_value = Some(#variant_name(Some(value))) }; enum_value = ::std::option::Option::Some(#variant_name(value))
};
let set_opt = quote! {
enum_value = ::std::option::Option::Some(#variant_name(::std::option::Option::Some(value)))
};
let set_vec = quote! { let set_vec = quote! {
match enum_value { match enum_value {
Some(ref mut v) => match v { Some(ref mut v) => match v {
#variant_name(ref mut v) => v.push(value), #variant_name(ref mut v) => v.push(value),
_ => return Err(std::string::String::from("Got sequence of different types")) _ => {
return ::std::result::Result::Err(
::std::string::String::from("Got sequence of different types"),
);
}
} }
None => { None => {
enum_value = Some(#variant_name(vec![value])); enum_value = ::std::option::Option::Some(#variant_name(vec![value]));
} }
} }
}; };

View File

@ -26,25 +26,33 @@ pub fn parse(
Field::FieldStruct { struct_name } => build_default_value( Field::FieldStruct { struct_name } => build_default_value(
&field, &field,
Some(quote!(#struct_name)), Some(quote!(#struct_name)),
quote!(#struct_name::default()), quote!(<#struct_name as ::std::default::Default>::default()),
), ),
Field::FieldOption { .. } => build_default_value(&field, None, quote!(None)), Field::FieldOption { .. } => {
Field::FieldVec { data_type } => match *data_type { build_default_value(&field, None, quote!(::std::option::Option::None))
Field::FieldStruct { ref struct_name } => {
build_default_value(&field, Some(quote!(Vec<#struct_name>)), quote!(vec![]))
} }
Field::FieldVec { data_type } => match *data_type {
Field::FieldStruct { ref struct_name } => build_default_value(
&field,
Some(quote!(::std::vec::Vec<#struct_name>)),
quote!(::std::vec![]),
),
Field::FieldOption { .. } | Field::FieldVec { .. } => { Field::FieldOption { .. } | Field::FieldVec { .. } => {
unimplemented!(); unimplemented!();
} }
simple_type => { simple_type => {
let type_token: TokenStream = simple_type.into(); let type_token: TokenStream = simple_type.into();
build_default_value(&field, Some(quote!(Vec<#type_token>)), quote!(vec![])) build_default_value(
&field,
Some(quote!(::std::vec::Vec<#type_token>)),
quote!(::std::vec![]),
)
} }
}, },
simple_type => { simple_type => {
let type_token: TokenStream = simple_type.into(); let type_token: TokenStream = simple_type.into();
let value_builder = quote!(#type_token::default()); let value_builder = quote!(<#type_token as ::std::default::Default>::default());
build_default_value(&field, Some(type_token), value_builder) build_default_value(&field, Some(type_token), value_builder)
} }
@ -69,13 +77,15 @@ pub fn parse(
Some(quote! { Some(quote! {
#[allow(non_snake_case, non_camel_case_types)] #[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label; struct #visitor_label;
impl<'de> Visitor<'de> for #visitor_label { impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
type Value = #struct_name; type Value = #struct_name;
fn visit_str(self, v: &str) -> Result<Self::Value, std::string::String> { fn visit_str(
self,
v: &::std::primitive::str,
) -> ::std::result::Result<Self::Value, ::std::string::String> {
let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">"; let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">";
let value : Result<#struct_name, std::string::String> = yaserde::de::from_str(&content); ::yaserde::de::from_str(&content)
value
} }
} }
}) })
@ -86,15 +96,12 @@ pub fn parse(
let visitor_label = field.get_visitor_ident(None); let visitor_label = field.get_visitor_ident(None);
let field_type: TokenStream = simple_type.into(); let field_type: TokenStream = simple_type.into();
let map_if_bool = let map_if_bool = if field_type.to_string() == "bool" {
if format!("{}", field_type) == "bool" { quote!(match v {
quote!(
match v {
"1" => "true", "1" => "true",
"0" => "false", "0" => "false",
_ => v, _ => v,
} })
)
} else { } else {
quote!(v) quote!(v)
}; };
@ -102,11 +109,14 @@ pub fn parse(
Some(quote! { Some(quote! {
#[allow(non_snake_case, non_camel_case_types)] #[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label; struct #visitor_label;
impl<'de> Visitor<'de> for #visitor_label { impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
type Value = #field_type; type Value = #field_type;
fn #visitor(self, v: &str) -> Result<Self::Value, std::string::String> { fn #visitor(
Ok(#field_type::from_str(#map_if_bool).unwrap()) self,
v: &::std::primitive::str,
) -> ::std::result::Result<Self::Value, ::std::string::String> {
::std::result::Result::Ok(#field_type::from_str(#map_if_bool).unwrap())
} }
} }
}) })
@ -146,7 +156,7 @@ pub fn parse(
// Don't count current struct's StartElement as substruct's StartElement // Don't count current struct's StartElement as substruct's StartElement
let _root = reader.next_event(); let _root = reader.next_event();
} }
if let Ok(XmlEvent::StartElement { .. }) = reader.peek() { if let Ok(::xml::reader::XmlEvent::StartElement { .. }) = reader.peek() {
// If substruct's start element found then deserialize substruct // If substruct's start element found then deserialize substruct
let value = #struct_name::deserialize(reader)?; let value = #struct_name::deserialize(reader)?;
#value_label #action; #value_label #action;
@ -174,10 +184,12 @@ pub fn parse(
}; };
match field.get_type() { match field.get_type() {
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}), Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }),
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}), Field::FieldOption { data_type } => {
Field::FieldVec { data_type } => visit_sub(data_type, quote! {.push(value)}), visit_sub(data_type, quote! { = ::std::option::Option::Some(value) })
simple_type => visit_simple(simple_type, quote! {= value}), }
Field::FieldVec { data_type } => visit_sub(data_type, quote! { .push(value) }),
simple_type => visit_simple(simple_type, quote! { = value }),
} }
}) })
.filter_map(|x| x) .filter_map(|x| x)
@ -193,11 +205,11 @@ pub fn parse(
match field.get_type() { match field.get_type() {
Field::FieldStruct { .. } => Some(quote! { Field::FieldStruct { .. } => Some(quote! {
#value_label = yaserde::de::from_str(&unused_xml_elements)?; #value_label = ::yaserde::de::from_str(&unused_xml_elements)?;
}), }),
Field::FieldOption { data_type } => match *data_type { Field::FieldOption { data_type } => match *data_type {
Field::FieldStruct { .. } => Some(quote! { Field::FieldStruct { .. } => Some(quote! {
#value_label = yaserde::de::from_str(&unused_xml_elements).ok(); #value_label = ::yaserde::de::from_str(&unused_xml_elements).ok();
}), }),
field_type => unimplemented!(r#""flatten" is not implemented for {:?}"#, field_type), field_type => unimplemented!(r#""flatten" is not implemented for {:?}"#, field_type),
}, },
@ -242,7 +254,7 @@ pub fn parse(
let visit_struct = |struct_name: syn::Path, action: TokenStream| { let visit_struct = |struct_name: syn::Path, action: TokenStream| {
visit( visit(
&action, &action,
&quote! {visit_str}, &quote! { visit_str },
&build_visitor_ident(&label_name, field.get_span(), Some(&struct_name)), &build_visitor_ident(&label_name, field.get_span(), Some(&struct_name)),
) )
}; };
@ -263,10 +275,12 @@ pub fn parse(
match field.get_type() { match field.get_type() {
Field::FieldString => visit_string(), Field::FieldString => visit_string(),
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}), Field::FieldOption { data_type } => {
visit_sub(data_type, quote! { = ::std::option::Option::Some(value) })
}
Field::FieldVec { .. } => unimplemented!(), Field::FieldVec { .. } => unimplemented!(),
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}), Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }),
simple_type => visit_simple(simple_type, quote! {= value}), simple_type => visit_simple(simple_type, quote! { = value }),
} }
}) })
.filter_map(|x| x) .filter_map(|x| x)
@ -281,18 +295,18 @@ pub fn parse(
let set_text = |action: &TokenStream| { let set_text = |action: &TokenStream| {
if field.is_text_content() { if field.is_text_content() {
Some(quote! {#label = #action;}) Some(quote! { #label = #action; })
} else { } else {
None None
} }
}; };
match field.get_type() { match field.get_type() {
Field::FieldString => set_text(&quote! {text_content.to_owned()}), Field::FieldString => set_text(&quote! { text_content.to_owned() }),
Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None, Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None,
simple_type => { simple_type => {
let type_token: TokenStream = simple_type.into(); let type_token: TokenStream = simple_type.into();
set_text(&quote! {#type_token::from_str(text_content).unwrap()}) set_text(&quote! { #type_token::from_str(text_content).unwrap() })
} }
} }
}) })
@ -320,24 +334,19 @@ pub fn parse(
let flatten = root_attributes.flatten; let flatten = root_attributes.flatten;
quote! { quote! {
use xml::reader::{XmlEvent, EventReader}; impl ::yaserde::YaDeserialize for #name {
use xml::writer::EventWriter;
use yaserde::Visitor;
#[allow(unknown_lints, unused_imports)]
use std::str::FromStr;
use log::{debug, trace};
impl YaDeserialize for #name {
#[allow(unused_variables)] #[allow(unused_variables)]
fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, std::string::String> { fn deserialize<R: ::std::io::Read>(
reader: &mut ::yaserde::de::Deserializer<R>,
) -> ::std::result::Result<Self, ::std::string::String> {
let (named_element, struct_namespace) = let (named_element, struct_namespace) =
if let XmlEvent::StartElement{name, ..} = reader.peek()?.to_owned() { if let ::xml::reader::XmlEvent::StartElement { name, .. } = reader.peek()?.to_owned() {
(name.local_name.to_owned(), name.namespace.clone()) (name.local_name.to_owned(), name.namespace.clone())
} else { } else {
(std::string::String::from(#root), None) (::std::string::String::from(#root), ::std::option::Option::None)
}; };
let start_depth = reader.depth(); let start_depth = reader.depth();
debug!("Struct {} @ {}: start to parse {:?}", stringify!(#name), start_depth, ::log::debug!("Struct {} @ {}: start to parse {:?}", stringify!(#name), start_depth,
named_element); named_element);
if reader.depth() == 0 { if reader.depth() == 0 {
@ -352,9 +361,12 @@ pub fn parse(
loop { loop {
let event = reader.peek()?.to_owned(); let event = reader.peek()?.to_owned();
trace!("Struct {} @ {}: matching {:?}", stringify!(#name), start_depth, event); ::log::trace!(
"Struct {} @ {}: matching {:?}",
::std::stringify!(#name), start_depth, event,
);
match event { match event {
XmlEvent::StartElement{ref name, ref attributes, ..} => { ::xml::reader::XmlEvent::StartElement{ref name, ref attributes, ..} => {
match name.local_name.as_str() { match name.local_name.as_str() {
#call_visitors #call_visitors
_ => { _ => {
@ -373,7 +385,7 @@ pub fn parse(
} }
depth += 1; depth += 1;
} }
XmlEvent::EndElement{ref name} => { ::xml::reader::XmlEvent::EndElement { ref name } => {
if name.local_name == named_element { if name.local_name == named_element {
#write_unused #write_unused
break; break;
@ -382,26 +394,26 @@ pub fn parse(
#write_unused #write_unused
depth -= 1; depth -= 1;
} }
XmlEvent::EndDocument => { ::xml::reader::XmlEvent::EndDocument => {
if #flatten { if #flatten {
break; break;
} }
} }
XmlEvent::Characters(ref text_content) => { ::xml::reader::XmlEvent::Characters(ref text_content) => {
#set_text #set_text
let event = reader.next_event()?; let event = reader.next_event()?;
#write_unused #write_unused
} }
event => { event => {
return Err(format!("unknown event {:?}", event)) return ::std::result::Result::Err(::std::format!("unknown event {:?}", event));
} }
} }
} }
#visit_unused #visit_unused
debug!("Struct {} @ {}: success", stringify!(#name), start_depth); ::log::debug!("Struct {} @ {}: success", stringify!(#name), start_depth);
Ok(#name{#struct_builder}) ::std::result::Result::Ok(#name{#struct_builder})
} }
} }
} }
@ -431,16 +443,16 @@ fn build_call_visitor(
#namespaces_matching #namespaces_matching
let result = reader.read_inner_value::<#field_type, _>(|reader| { let result = reader.read_inner_value::<#field_type, _>(|reader| {
if let Ok(XmlEvent::Characters(s)) = reader.peek() { if let ::std::result::Result::Ok(::xml::reader::XmlEvent::Characters(s)) = reader.peek() {
let val = visitor.#visitor(&s); let val = visitor.#visitor(&s);
let _event = reader.next_event()?; let _event = reader.next_event()?;
val val
} else { } else {
Err(format!("unable to parse content for {}", #label_name)) ::std::result::Result::Err(::std::format!("unable to parse content for {}", #label_name))
} }
}); });
if let Ok(value) = result { if let ::std::result::Result::Ok(value) = result {
#value_label#action #value_label#action
} }
} }
@ -478,19 +490,19 @@ fn build_code_for_unused_xml_events(
) { ) {
( (
Some(quote! { Some(quote! {
let mut buf = Vec::new(); let mut buf = ::std::vec![];
let mut writer = Some(EventWriter::new(&mut buf)); let mut writer = ::std::option::Option::Some(::xml::writer::EventWriter::new(&mut buf));
}), }),
Some(quote! { Some(quote! {
if let Some(ref mut w) = writer { if let ::std::option::Option::Some(ref mut w) = writer {
if w.write(event.as_writer_event().unwrap()).is_err() { if w.write(event.as_writer_event().unwrap()).is_err() {
writer = None; writer = ::std::option::Option::None;
} }
} }
}), }),
Some(quote! { Some(quote! {
if writer.is_some() { if writer.is_some() {
let unused_xml_elements = std::string::String::from_utf8(buf).unwrap(); let unused_xml_elements = ::std::string::String::from_utf8(buf).unwrap();
#call_flatten_visitors #call_flatten_visitors
} }
}), }),

View File

@ -5,7 +5,6 @@ pub mod expand_struct;
use crate::common::YaSerdeAttribute; use crate::common::YaSerdeAttribute;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::quote;
use syn::Ident;
pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream, String> { pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream, String> {
let name = &ast.ident; let name = &ast.ident;
@ -30,15 +29,13 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream,
syn::Data::Union(ref _data_union) => unimplemented!(), syn::Data::Union(ref _data_union) => unimplemented!(),
}; };
let dummy_const = Ident::new(&format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), name.span()); Ok(quote! {
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = { const _: () = {
extern crate yaserde as _yaserde; use ::std::str::FromStr as _;
use ::yaserde::Visitor as _;
#impl_block #impl_block
}; };
}; })
Ok(generated)
} }

View File

@ -16,14 +16,14 @@ pub fn enclose_characters(label: &Option<Ident>, label_name: String) -> TokenStr
fn enclose_xml_event(label_name: String, yaserde_format: TokenStream) -> TokenStream { fn enclose_xml_event(label_name: String, yaserde_format: TokenStream) -> TokenStream {
quote! { quote! {
let start_event = XmlEvent::start_element(#label_name); let start_event = ::xml::writer::XmlEvent::start_element(#label_name);
writer.write(start_event).map_err(|e| e.to_string())?; writer.write(start_event).map_err(|e| e.to_string())?;
let yaserde_value = #yaserde_format; let yaserde_value = #yaserde_format;
let data_event = XmlEvent::characters(&yaserde_value); let data_event = ::xml::writer::XmlEvent::characters(&yaserde_value);
writer.write(data_event).map_err(|e| e.to_string())?; writer.write(data_event).map_err(|e| e.to_string())?;
let end_event = XmlEvent::end_element(); let end_event = ::xml::writer::XmlEvent::end_element();
writer.write(end_event).map_err(|e| e.to_string())?; writer.write(end_event).map_err(|e| e.to_string())?;
} }
} }

View File

@ -42,7 +42,7 @@ fn inner_enum_inspector(
match variant.fields { match variant.fields {
Fields::Unit => Some(quote! { Fields::Unit => Some(quote! {
&#name::#label => { &#name::#label => {
let data_event = XmlEvent::characters(#label_name); let data_event = ::xml::writer::XmlEvent::characters(#label_name);
writer.write(data_event).map_err(|e| e.to_string())?; writer.write(data_event).map_err(|e| e.to_string())?;
} }
}), }),
@ -57,7 +57,7 @@ fn inner_enum_inspector(
if field.is_text_content() { if field.is_text_content() {
return Some(quote!( return Some(quote!(
let data_event = XmlEvent::characters(&self.#field_label); let data_event = ::xml::writer::XmlEvent::characters(&self.#field_label);
writer.write(data_event).map_err(|e| e.to_string())?; writer.write(data_event).map_err(|e| e.to_string())?;
)); ));
} }
@ -79,15 +79,16 @@ fn inner_enum_inspector(
| Field::FieldF64 => Some({ | Field::FieldF64 => Some({
quote! { quote! {
match self { match self {
&#name::#label{ref #field_label, ..} => { &#name::#label { ref #field_label, .. } => {
let struct_start_event = XmlEvent::start_element(#field_label_name); let struct_start_event =
::xml::writer::XmlEvent::start_element(#field_label_name);
writer.write(struct_start_event).map_err(|e| e.to_string())?; writer.write(struct_start_event).map_err(|e| e.to_string())?;
let string_value = #field_label.to_string(); let string_value = #field_label.to_string();
let data_event = XmlEvent::characters(&string_value); let data_event = ::xml::writer::XmlEvent::characters(&string_value);
writer.write(data_event).map_err(|e| e.to_string())?; writer.write(data_event).map_err(|e| e.to_string())?;
let struct_end_event = XmlEvent::end_element(); let struct_end_event = ::xml::writer::XmlEvent::end_element();
writer.write(struct_end_event).map_err(|e| e.to_string())?; writer.write(struct_end_event).map_err(|e| e.to_string())?;
}, },
_ => {}, _ => {},
@ -97,7 +98,9 @@ fn inner_enum_inspector(
Field::FieldStruct { .. } => Some(quote! { Field::FieldStruct { .. } => Some(quote! {
match self { match self {
&#name::#label{ref #field_label, ..} => { &#name::#label{ref #field_label, ..} => {
writer.set_start_event_name(Some(#field_label_name.to_string())); writer.set_start_event_name(
::std::option::Option::Some(#field_label_name.to_string()),
);
writer.set_skip_start_end(false); writer.set_skip_start_end(false);
#field_label.serialize(writer)?; #field_label.serialize(writer)?;
}, },
@ -106,9 +109,11 @@ fn inner_enum_inspector(
}), }),
Field::FieldVec { .. } => Some(quote! { Field::FieldVec { .. } => Some(quote! {
match self { match self {
&#name::#label{ref #field_label, ..} => { &#name::#label { ref #field_label, .. } => {
for item in #field_label { for item in #field_label {
writer.set_start_event_name(Some(#field_label_name.to_string())); writer.set_start_event_name(
::std::option::Option::Some(#field_label_name.to_string()),
);
writer.set_skip_start_end(false); writer.set_skip_start_end(false);
item.serialize(writer)?; item.serialize(writer)?;
} }
@ -137,29 +142,29 @@ fn inner_enum_inspector(
.map(|field| { .map(|field| {
let write_element = |action: &TokenStream| { let write_element = |action: &TokenStream| {
quote! { quote! {
let struct_start_event = XmlEvent::start_element(#label_name); let struct_start_event = ::xml::writer::XmlEvent::start_element(#label_name);
writer.write(struct_start_event).map_err(|e| e.to_string())?; writer.write(struct_start_event).map_err(|e| e.to_string())?;
#action #action
let struct_end_event = XmlEvent::end_element(); let struct_end_event = ::xml::writer::XmlEvent::end_element();
writer.write(struct_end_event).map_err(|e| e.to_string())?; writer.write(struct_end_event).map_err(|e| e.to_string())?;
} }
}; };
let write_string_chars = quote! { let write_string_chars = quote! {
let data_event = XmlEvent::characters(item); let data_event = ::xml::writer::XmlEvent::characters(item);
writer.write(data_event).map_err(|e| e.to_string())?; writer.write(data_event).map_err(|e| e.to_string())?;
}; };
let write_simple_type = write_element(&quote! { let write_simple_type = write_element(&quote! {
let s = item.to_string(); let s = item.to_string();
let data_event = XmlEvent::characters(&s); let data_event = ::xml::writer::XmlEvent::characters(&s);
writer.write(data_event).map_err(|e| e.to_string())?; writer.write(data_event).map_err(|e| e.to_string())?;
}); });
let serialize = quote! { let serialize = quote! {
writer.set_start_event_name(None); writer.set_start_event_name(::std::option::Option::None);
writer.set_skip_start_end(true); writer.set_skip_start_end(true);
item.serialize(writer)?; item.serialize(writer)?;
}; };
@ -187,7 +192,7 @@ fn inner_enum_inspector(
let write = write_sub_type(*data_type); let write = write_sub_type(*data_type);
Some(match_field(&quote! { Some(match_field(&quote! {
if let Some(item) = item { if let ::std::option::Option::Some(item) = item {
#write #write
} }
})) }))

View File

@ -45,7 +45,7 @@ pub fn serialize(
Field::FieldString => field.ser_wrap_default_attribute( Field::FieldString => field.ser_wrap_default_attribute(
None, None,
quote!({ quote!({
if let Some(ref value) = self.#label { if let ::std::option::Option::Some(ref value) = self.#label {
struct_start_event.attr(#label_name, value) struct_start_event.attr(#label_name, value)
} else { } else {
struct_start_event struct_start_event
@ -63,9 +63,11 @@ pub fn serialize(
| Field::FieldU64 | Field::FieldU64
| Field::FieldF32 | Field::FieldF32
| Field::FieldF64 => field.ser_wrap_default_attribute( | Field::FieldF64 => field.ser_wrap_default_attribute(
Some(quote!(self.#label.map_or_else(|| std::string::String::new(), |v| v.to_string()))), Some(
quote!(self.#label.map_or_else(|| ::std::string::String::new(), |v| v.to_string())),
),
quote!({ quote!({
if let Some(ref value) = self.#label { if let ::std::option::Option::Some(ref value) = self.#label {
struct_start_event.attr(#label_name, &yaserde_inner) struct_start_event.attr(#label_name, &yaserde_inner)
} else { } else {
struct_start_event struct_start_event
@ -79,7 +81,7 @@ pub fn serialize(
field.ser_wrap_default_attribute( field.ser_wrap_default_attribute(
None, None,
quote!({ quote!({
if let Some(ref yaserde_list) = self.#label { if let ::std::option::Option::Some(ref yaserde_list) = self.#label {
for yaserde_item in yaserde_list.iter() { for yaserde_item in yaserde_list.iter() {
#inner #inner
} }
@ -88,11 +90,16 @@ pub fn serialize(
) )
} }
Field::FieldStruct { .. } => field.ser_wrap_default_attribute( Field::FieldStruct { .. } => field.ser_wrap_default_attribute(
Some(quote!(self.#label Some(quote! {
self.#label
.as_ref() .as_ref()
.map_or_else(|| Ok(std::string::String::new()), |v| yaserde::ser::to_string_content(v))?)), .map_or_else(
|| ::std::result::Result::Ok(::std::string::String::new()),
|v| ::yaserde::ser::to_string_content(v),
)?
}),
quote!({ quote!({
if let Some(ref yaserde_struct) = self.#label { if let ::std::option::Option::Some(ref yaserde_struct) = self.#label {
struct_start_event.attr(#label_name, &yaserde_inner) struct_start_event.attr(#label_name, &yaserde_inner)
} else { } else {
struct_start_event struct_start_event
@ -102,7 +109,7 @@ pub fn serialize(
Field::FieldOption { .. } => unimplemented!(), Field::FieldOption { .. } => unimplemented!(),
}, },
Field::FieldStruct { .. } => field.ser_wrap_default_attribute( Field::FieldStruct { .. } => field.ser_wrap_default_attribute(
Some(quote!(yaserde::ser::to_string_content(&self.#label)?)), Some(quote! { ::yaserde::ser::to_string_content(&self.#label)? }),
quote!({ quote!({
struct_start_event.attr(#label_name, &yaserde_inner) struct_start_event.attr(#label_name, &yaserde_inner)
}), }),
@ -116,12 +123,15 @@ pub fn serialize(
match field.get_type() { match field.get_type() {
Field::FieldStruct { .. } => { Field::FieldStruct { .. } => {
quote!( quote!(
let (attributes, namespace) = self.#label.serialize_attributes(vec![], xml::namespace::Namespace::empty())?; let (attributes, namespace) = self.#label.serialize_attributes(
::std::vec![],
::xml::namespace::Namespace::empty(),
)?;
child_attributes_namespace.extend(&namespace); child_attributes_namespace.extend(&namespace);
child_attributes.extend(attributes); child_attributes.extend(attributes);
) )
} }
_ => quote!() _ => quote!(),
} }
} }
}) })
@ -136,7 +146,7 @@ pub fn serialize(
let label = field.label(); let label = field.label();
if field.is_text_content() { if field.is_text_content() {
return Some(quote!( return Some(quote!(
let data_event = XmlEvent::characters(&self.#label); let data_event = ::xml::writer::XmlEvent::characters(&self.#label);
writer.write(data_event).map_err(|e| e.to_string())?; writer.write(data_event).map_err(|e| e.to_string())?;
)); ));
} }
@ -188,7 +198,7 @@ pub fn serialize(
Some(quote! { Some(quote! {
#conditions { #conditions {
if let Some(ref yaserde_items) = &self.#label { if let ::std::option::Option::Some(ref yaserde_items) = &self.#label {
for yaserde_item in yaserde_items.iter() { for yaserde_item in yaserde_items.iter() {
#inner #inner
} }
@ -198,16 +208,16 @@ pub fn serialize(
} }
Field::FieldStruct { .. } => Some(if field.is_flatten() { Field::FieldStruct { .. } => Some(if field.is_flatten() {
quote! { quote! {
if let Some(ref item) = &self.#label { if let ::std::option::Option::Some(ref item) = &self.#label {
writer.set_start_event_name(None); writer.set_start_event_name(::std::option::Option::None);
writer.set_skip_start_end(true); writer.set_skip_start_end(true);
item.serialize(writer)?; item.serialize(writer)?;
} }
} }
} else { } else {
quote! { quote! {
if let Some(ref item) = &self.#label { if let ::std::option::Option::Some(ref item) = &self.#label {
writer.set_start_event_name(Some(#label_name.to_string())); writer.set_start_event_name(::std::option::Option::Some(#label_name.to_string()));
writer.set_skip_start_end(false); writer.set_skip_start_end(false);
item.serialize(writer)?; item.serialize(writer)?;
} }
@ -217,9 +227,12 @@ pub fn serialize(
}, },
Field::FieldStruct { .. } => { Field::FieldStruct { .. } => {
let (start_event, skip_start) = if field.is_flatten() { let (start_event, skip_start) = if field.is_flatten() {
(quote!(None), true) (quote!(::std::option::Option::None), true)
} else { } else {
(quote!(Some(#label_name.to_string())), false) (
quote!(::std::option::Option::Some(#label_name.to_string())),
false,
)
}; };
Some(quote! { Some(quote! {
@ -272,7 +285,7 @@ pub fn serialize(
if field.is_flatten() { if field.is_flatten() {
Some(quote! { Some(quote! {
for item in &self.#label { for item in &self.#label {
writer.set_start_event_name(None); writer.set_start_event_name(::std::option::Option::None);
writer.set_skip_start_end(true); writer.set_skip_start_end(true);
item.serialize(writer)?; item.serialize(writer)?;
} }
@ -280,7 +293,7 @@ pub fn serialize(
} else { } else {
Some(quote! { Some(quote! {
for item in &self.#label { for item in &self.#label {
writer.set_start_event_name(Some(#label_name.to_string())); writer.set_start_event_name(::std::option::Option::Some(#label_name.to_string()));
writer.set_skip_start_end(false); writer.set_skip_start_end(false);
item.serialize(writer)?; item.serialize(writer)?;
} }

View File

@ -15,26 +15,32 @@ pub fn implement_serializer(
let flatten = attributes.flatten; let flatten = attributes.flatten;
quote! { quote! {
use xml::writer::XmlEvent; impl ::yaserde::YaSerialize for #name {
impl YaSerialize for #name {
#[allow(unused_variables)] #[allow(unused_variables)]
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) fn serialize<W: ::std::io::Write>(
-> Result<(), std::string::String> { &self,
writer: &mut ::yaserde::ser::Serializer<W>,
) -> ::std::result::Result<(), ::std::string::String> {
let skip = writer.skip_start_end(); let skip = writer.skip_start_end();
if !#flatten && !skip { if !#flatten && !skip {
let mut child_attributes = vec![]; let mut child_attributes = ::std::vec![];
let mut child_attributes_namespace = xml::namespace::Namespace::empty(); let mut child_attributes_namespace = ::xml::namespace::Namespace::empty();
let yaserde_label = writer.get_start_event_name().unwrap_or_else(|| #root.to_string()); let yaserde_label = writer.get_start_event_name().unwrap_or_else(|| #root.to_string());
let struct_start_event = XmlEvent::start_element(yaserde_label.as_ref())#namespaces_definition; let struct_start_event =
::xml::writer::XmlEvent::start_element(yaserde_label.as_ref()) #namespaces_definition;
#append_attributes #append_attributes
let event : xml::writer::events::XmlEvent = struct_start_event.into(); let event: ::xml::writer::events::XmlEvent = struct_start_event.into();
if let xml::writer::events::XmlEvent::StartElement{name, attributes, namespace} = event { if let ::xml::writer::events::XmlEvent::StartElement {
let mut attributes: Vec<xml::attribute::OwnedAttribute> = attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect(); name,
attributes,
namespace,
} = event {
let mut attributes: ::std::vec::Vec<::xml::attribute::OwnedAttribute> =
attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect();
attributes.extend(child_attributes); attributes.extend(child_attributes);
let all_attributes = attributes.iter().map(|ca| ca.borrow()).collect(); let all_attributes = attributes.iter().map(|ca| ca.borrow()).collect();
@ -42,10 +48,10 @@ pub fn implement_serializer(
let mut all_namespaces = namespace.into_owned(); let mut all_namespaces = namespace.into_owned();
all_namespaces.extend(&child_attributes_namespace); all_namespaces.extend(&child_attributes_namespace);
writer.write(xml::writer::events::XmlEvent::StartElement{ writer.write(::xml::writer::events::XmlEvent::StartElement{
name, name,
attributes: std::borrow::Cow::Owned(all_attributes), attributes: ::std::borrow::Cow::Owned(all_attributes),
namespace: std::borrow::Cow::Owned(all_namespaces) namespace: ::std::borrow::Cow::Owned(all_namespaces)
}).map_err(|e| e.to_string())?; }).map_err(|e| e.to_string())?;
} else { } else {
unreachable!() unreachable!()
@ -55,30 +61,41 @@ pub fn implement_serializer(
#inner_inspector #inner_inspector
if !#flatten && !skip { if !#flatten && !skip {
let struct_end_event = XmlEvent::end_element(); let struct_end_event = ::xml::writer::XmlEvent::end_element();
writer.write(struct_end_event).map_err(|e| e.to_string())?; writer.write(struct_end_event).map_err(|e| e.to_string())?;
} }
Ok(()) ::std::result::Result::Ok(())
} }
fn serialize_attributes(&self, mut source_attributes: Vec<xml::attribute::OwnedAttribute>, mut source_namespace: xml::namespace::Namespace) -> Result<(Vec<xml::attribute::OwnedAttribute>, xml::namespace::Namespace), std::string::String> { fn serialize_attributes(
let mut child_attributes : Vec<xml::attribute::OwnedAttribute> = vec![]; &self,
let mut child_attributes_namespace = xml::namespace::Namespace::empty(); mut source_attributes: ::std::vec::Vec<::xml::attribute::OwnedAttribute>,
mut source_namespace: ::xml::namespace::Namespace,
) -> ::std::result::Result<
(::std::vec::Vec<::xml::attribute::OwnedAttribute>, ::xml::namespace::Namespace),
::std::string::String
> {
let mut child_attributes = ::std::vec::Vec::<::xml::attribute::OwnedAttribute>::new();
let mut child_attributes_namespace = ::xml::namespace::Namespace::empty();
let struct_start_event =
::xml::writer::XmlEvent::start_element("temporary_element_to_generate_attributes")
#namespaces_definition;
let struct_start_event = XmlEvent::start_element("temporary_element_to_generate_attributes")#namespaces_definition;
#append_attributes #append_attributes
let event : xml::writer::events::XmlEvent = struct_start_event.into(); let event: ::xml::writer::events::XmlEvent = struct_start_event.into();
if let xml::writer::events::XmlEvent::StartElement{attributes, namespace, ..} = event { if let ::xml::writer::events::XmlEvent::StartElement { attributes, namespace, .. } = event {
source_namespace.extend(&namespace.into_owned()); source_namespace.extend(&namespace.into_owned());
source_namespace.extend(&child_attributes_namespace); source_namespace.extend(&child_attributes_namespace);
let a: Vec<xml::attribute::OwnedAttribute> = attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect(); let a: ::std::vec::Vec<::xml::attribute::OwnedAttribute> =
attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect();
source_attributes.extend(a); source_attributes.extend(a);
source_attributes.extend(child_attributes); source_attributes.extend(child_attributes);
Ok((source_attributes, source_namespace)) ::std::result::Result::Ok((source_attributes, source_namespace))
} else { } else {
unreachable!(); unreachable!();
} }

View File

@ -8,7 +8,6 @@ pub mod namespace;
use crate::common::YaSerdeAttribute; use crate::common::YaSerdeAttribute;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::quote;
use syn::Ident;
pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, String> { pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, String> {
let name = &ast.ident; let name = &ast.ident;
@ -33,15 +32,12 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, St
syn::Data::Union(ref _data_union) => unimplemented!(), syn::Data::Union(ref _data_union) => unimplemented!(),
}; };
let dummy_const = Ident::new(&format!("_IMPL_YA_SERIALIZE_FOR_{}", name), name.span()); Ok(quote! {
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = { const _: () = {
extern crate yaserde as _yaserde; use ::std::str::FromStr as _;
#impl_block #impl_block
}; };
}; })
Ok(generated)
} }