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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -155,7 +155,8 @@ impl YaSerdeAttribute {
match namespace.as_str() {
#namespaces_matches
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);
}
}

View File

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

View File

@ -26,35 +26,31 @@ pub fn parse(
let flatten = root_attributes.flatten;
quote! {
use xml::reader::XmlEvent;
use yaserde::Visitor;
#[allow(unknown_lints, unused_imports)]
use std::str::FromStr;
use log::{debug, trace};
impl YaDeserialize for #name {
impl ::yaserde::YaDeserialize for #name {
#[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) =
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())
} else {
(std::string::String::from(#root), None)
(::std::string::String::from(#root), ::std::option::Option::None)
};
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
#[allow(unused_assignments, unused_mut)]
let mut enum_value = None;
let mut enum_value = ::std::option::Option::None;
loop {
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 {
XmlEvent::StartElement{ref name, ref attributes, ..} => {
::xml::reader::XmlEvent::StartElement { ref name, ref attributes, .. } => {
match name.local_name.as_str() {
#match_to_enum
_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_to_enum
_ => {}
}
}
}
XmlEvent::EndElement{ref name} => {
::xml::reader::XmlEvent::EndElement { ref name } => {
if name.local_name == named_element {
break;
}
let _root = reader.next_event();
}
XmlEvent::Characters(ref text_content) => {
::xml::reader::XmlEvent::Characters(ref text_content) => {
let _root = reader.next_event();
}
XmlEvent::EndDocument => {
::xml::reader::XmlEvent::EndDocument => {
if #flatten {
break;
}
return Err(format!("End of document, missing some content ?"))
return ::std::result::Result::Err(
::std::format!("End of document, missing some content ?"),
);
}
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 {
Some(value) => Ok(value),
None => {
Ok(#name::default())
::std::option::Option::Some(value) => ::std::result::Result::Ok(value),
::std::option::Option::None => {
::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 {
Fields::Unit => Some(quote! {
#xml_element_name => {
enum_value = Some(#variant_name);
enum_value = ::std::option::Option::Some(#variant_name);
}
}),
Fields::Unnamed(ref fields) => {
@ -159,10 +157,13 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
Some(quote! {
#[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label;
impl<'de> Visitor<'de> for #visitor_label {
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
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
}
}
@ -176,7 +177,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
make_visitor(
&visitor,
&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! {
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
},
)
@ -231,18 +233,22 @@ fn build_unnamed_visitor_calls(
let visitor = #visitor_label{};
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("");
}
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)
} 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
}
})
@ -262,16 +268,24 @@ fn build_unnamed_visitor_calls(
})
};
let set_val = quote! { enum_value = Some(#variant_name(value)) };
let set_opt = quote! { enum_value = Some(#variant_name(Some(value))) };
let set_val = quote! {
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! {
match enum_value {
Some(ref mut v) => match v {
#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 => {
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,
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::FieldVec { data_type } => match *data_type {
Field::FieldStruct { ref struct_name } => {
build_default_value(&field, Some(quote!(Vec<#struct_name>)), quote!(vec![]))
Field::FieldOption { .. } => {
build_default_value(&field, None, quote!(::std::option::Option::None))
}
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 { .. } => {
unimplemented!();
}
simple_type => {
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 => {
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)
}
@ -69,13 +77,15 @@ pub fn parse(
Some(quote! {
#[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label;
impl<'de> Visitor<'de> for #visitor_label {
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
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 value : Result<#struct_name, std::string::String> = yaserde::de::from_str(&content);
value
::yaserde::de::from_str(&content)
}
}
})
@ -86,15 +96,12 @@ pub fn parse(
let visitor_label = field.get_visitor_ident(None);
let field_type: TokenStream = simple_type.into();
let map_if_bool =
if format!("{}", field_type) == "bool" {
quote!(
match v {
let map_if_bool = if field_type.to_string() == "bool" {
quote!(match v {
"1" => "true",
"0" => "false",
_ => v,
}
)
})
} else {
quote!(v)
};
@ -102,11 +109,14 @@ pub fn parse(
Some(quote! {
#[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label;
impl<'de> Visitor<'de> for #visitor_label {
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
type Value = #field_type;
fn #visitor(self, v: &str) -> Result<Self::Value, std::string::String> {
Ok(#field_type::from_str(#map_if_bool).unwrap())
fn #visitor(
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
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
let value = #struct_name::deserialize(reader)?;
#value_label #action;
@ -175,7 +185,9 @@ pub fn parse(
match field.get_type() {
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 } => {
visit_sub(data_type, quote! { = ::std::option::Option::Some(value) })
}
Field::FieldVec { data_type } => visit_sub(data_type, quote! { .push(value) }),
simple_type => visit_simple(simple_type, quote! { = value }),
}
@ -193,11 +205,11 @@ pub fn parse(
match field.get_type() {
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::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),
},
@ -263,7 +275,9 @@ pub fn parse(
match field.get_type() {
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::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }),
simple_type => visit_simple(simple_type, quote! { = value }),
@ -320,24 +334,19 @@ pub fn parse(
let flatten = root_attributes.flatten;
quote! {
use xml::reader::{XmlEvent, EventReader};
use xml::writer::EventWriter;
use yaserde::Visitor;
#[allow(unknown_lints, unused_imports)]
use std::str::FromStr;
use log::{debug, trace};
impl YaDeserialize for #name {
impl ::yaserde::YaDeserialize for #name {
#[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) =
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())
} else {
(std::string::String::from(#root), None)
(::std::string::String::from(#root), ::std::option::Option::None)
};
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);
if reader.depth() == 0 {
@ -352,9 +361,12 @@ pub fn parse(
loop {
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 {
XmlEvent::StartElement{ref name, ref attributes, ..} => {
::xml::reader::XmlEvent::StartElement{ref name, ref attributes, ..} => {
match name.local_name.as_str() {
#call_visitors
_ => {
@ -373,7 +385,7 @@ pub fn parse(
}
depth += 1;
}
XmlEvent::EndElement{ref name} => {
::xml::reader::XmlEvent::EndElement { ref name } => {
if name.local_name == named_element {
#write_unused
break;
@ -382,26 +394,26 @@ pub fn parse(
#write_unused
depth -= 1;
}
XmlEvent::EndDocument => {
::xml::reader::XmlEvent::EndDocument => {
if #flatten {
break;
}
}
XmlEvent::Characters(ref text_content) => {
::xml::reader::XmlEvent::Characters(ref text_content) => {
#set_text
let event = reader.next_event()?;
#write_unused
}
event => {
return Err(format!("unknown event {:?}", event))
return ::std::result::Result::Err(::std::format!("unknown event {:?}", event));
}
}
}
#visit_unused
debug!("Struct {} @ {}: success", stringify!(#name), start_depth);
Ok(#name{#struct_builder})
::log::debug!("Struct {} @ {}: success", stringify!(#name), start_depth);
::std::result::Result::Ok(#name{#struct_builder})
}
}
}
@ -431,16 +443,16 @@ fn build_call_visitor(
#namespaces_matching
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 _event = reader.next_event()?;
val
} 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
}
}
@ -478,19 +490,19 @@ fn build_code_for_unused_xml_events(
) {
(
Some(quote! {
let mut buf = Vec::new();
let mut writer = Some(EventWriter::new(&mut buf));
let mut buf = ::std::vec![];
let mut writer = ::std::option::Option::Some(::xml::writer::EventWriter::new(&mut buf));
}),
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() {
writer = None;
writer = ::std::option::Option::None;
}
}
}),
Some(quote! {
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
}
}),

View File

@ -5,7 +5,6 @@ pub mod expand_struct;
use crate::common::YaSerdeAttribute;
use proc_macro2::TokenStream;
use quote::quote;
use syn::Ident;
pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream, String> {
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!(),
};
let dummy_const = Ident::new(&format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), name.span());
let generated = quote! {
Ok(quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
extern crate yaserde as _yaserde;
const _: () = {
use ::std::str::FromStr as _;
use ::yaserde::Visitor as _;
#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 {
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())?;
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())?;
let end_event = XmlEvent::end_element();
let end_event = ::xml::writer::XmlEvent::end_element();
writer.write(end_event).map_err(|e| e.to_string())?;
}
}

View File

@ -42,7 +42,7 @@ fn inner_enum_inspector(
match variant.fields {
Fields::Unit => Some(quote! {
&#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())?;
}
}),
@ -57,7 +57,7 @@ fn inner_enum_inspector(
if field.is_text_content() {
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())?;
));
}
@ -80,14 +80,15 @@ fn inner_enum_inspector(
quote! {
match self {
&#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())?;
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())?;
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())?;
},
_ => {},
@ -97,7 +98,9 @@ fn inner_enum_inspector(
Field::FieldStruct { .. } => Some(quote! {
match self {
&#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);
#field_label.serialize(writer)?;
},
@ -108,7 +111,9 @@ fn inner_enum_inspector(
match self {
&#name::#label { ref #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);
item.serialize(writer)?;
}
@ -137,29 +142,29 @@ fn inner_enum_inspector(
.map(|field| {
let write_element = |action: &TokenStream| {
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())?;
#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())?;
}
};
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())?;
};
let write_simple_type = write_element(&quote! {
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())?;
});
let serialize = quote! {
writer.set_start_event_name(None);
writer.set_start_event_name(::std::option::Option::None);
writer.set_skip_start_end(true);
item.serialize(writer)?;
};
@ -187,7 +192,7 @@ fn inner_enum_inspector(
let write = write_sub_type(*data_type);
Some(match_field(&quote! {
if let Some(item) = item {
if let ::std::option::Option::Some(item) = item {
#write
}
}))

View File

@ -45,7 +45,7 @@ pub fn serialize(
Field::FieldString => field.ser_wrap_default_attribute(
None,
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)
} else {
struct_start_event
@ -63,9 +63,11 @@ pub fn serialize(
| Field::FieldU64
| Field::FieldF32
| 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!({
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)
} else {
struct_start_event
@ -79,7 +81,7 @@ pub fn serialize(
field.ser_wrap_default_attribute(
None,
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() {
#inner
}
@ -88,11 +90,16 @@ pub fn serialize(
)
}
Field::FieldStruct { .. } => field.ser_wrap_default_attribute(
Some(quote!(self.#label
Some(quote! {
self.#label
.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!({
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)
} else {
struct_start_event
@ -102,7 +109,7 @@ pub fn serialize(
Field::FieldOption { .. } => unimplemented!(),
},
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!({
struct_start_event.attr(#label_name, &yaserde_inner)
}),
@ -116,12 +123,15 @@ pub fn serialize(
match field.get_type() {
Field::FieldStruct { .. } => {
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.extend(attributes);
)
}
_ => quote!()
_ => quote!(),
}
}
})
@ -136,7 +146,7 @@ pub fn serialize(
let label = field.label();
if field.is_text_content() {
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())?;
));
}
@ -188,7 +198,7 @@ pub fn serialize(
Some(quote! {
#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() {
#inner
}
@ -198,16 +208,16 @@ pub fn serialize(
}
Field::FieldStruct { .. } => Some(if field.is_flatten() {
quote! {
if let Some(ref item) = &self.#label {
writer.set_start_event_name(None);
if let ::std::option::Option::Some(ref item) = &self.#label {
writer.set_start_event_name(::std::option::Option::None);
writer.set_skip_start_end(true);
item.serialize(writer)?;
}
}
} else {
quote! {
if let Some(ref item) = &self.#label {
writer.set_start_event_name(Some(#label_name.to_string()));
if let ::std::option::Option::Some(ref item) = &self.#label {
writer.set_start_event_name(::std::option::Option::Some(#label_name.to_string()));
writer.set_skip_start_end(false);
item.serialize(writer)?;
}
@ -217,9 +227,12 @@ pub fn serialize(
},
Field::FieldStruct { .. } => {
let (start_event, skip_start) = if field.is_flatten() {
(quote!(None), true)
(quote!(::std::option::Option::None), true)
} else {
(quote!(Some(#label_name.to_string())), false)
(
quote!(::std::option::Option::Some(#label_name.to_string())),
false,
)
};
Some(quote! {
@ -272,7 +285,7 @@ pub fn serialize(
if field.is_flatten() {
Some(quote! {
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);
item.serialize(writer)?;
}
@ -280,7 +293,7 @@ pub fn serialize(
} else {
Some(quote! {
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);
item.serialize(writer)?;
}

View File

@ -15,26 +15,32 @@ pub fn implement_serializer(
let flatten = attributes.flatten;
quote! {
use xml::writer::XmlEvent;
impl YaSerialize for #name {
impl ::yaserde::YaSerialize for #name {
#[allow(unused_variables)]
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>)
-> Result<(), std::string::String> {
fn serialize<W: ::std::io::Write>(
&self,
writer: &mut ::yaserde::ser::Serializer<W>,
) -> ::std::result::Result<(), ::std::string::String> {
let skip = writer.skip_start_end();
if !#flatten && !skip {
let mut child_attributes = vec![];
let mut child_attributes_namespace = xml::namespace::Namespace::empty();
let mut child_attributes = ::std::vec![];
let mut child_attributes_namespace = ::xml::namespace::Namespace::empty();
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
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 {
let mut attributes: Vec<xml::attribute::OwnedAttribute> = attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect();
if let ::xml::writer::events::XmlEvent::StartElement {
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);
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();
all_namespaces.extend(&child_attributes_namespace);
writer.write(xml::writer::events::XmlEvent::StartElement{
writer.write(::xml::writer::events::XmlEvent::StartElement{
name,
attributes: std::borrow::Cow::Owned(all_attributes),
namespace: std::borrow::Cow::Owned(all_namespaces)
attributes: ::std::borrow::Cow::Owned(all_attributes),
namespace: ::std::borrow::Cow::Owned(all_namespaces)
}).map_err(|e| e.to_string())?;
} else {
unreachable!()
@ -55,30 +61,41 @@ pub fn implement_serializer(
#inner_inspector
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())?;
}
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> {
let mut child_attributes : Vec<xml::attribute::OwnedAttribute> = vec![];
let mut child_attributes_namespace = xml::namespace::Namespace::empty();
fn serialize_attributes(
&self,
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
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(&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(child_attributes);
Ok((source_attributes, source_namespace))
::std::result::Result::Ok((source_attributes, source_namespace))
} else {
unreachable!();
}

View File

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