skip serialization if value equals to default
This commit is contained in:
@@ -4,7 +4,7 @@ rust:
|
|||||||
- 1.27.0
|
- 1.27.0
|
||||||
- 1.28.0
|
- 1.28.0
|
||||||
- 1.29.0
|
- 1.29.0
|
||||||
- 1.30.0
|
- 1.31.0
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ This library will support XML de/ser-ializing with all specific features.
|
|||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
- [x] **attribute**: this field is defined as an attribute
|
- [x] **attribute**: this field is defined as an attribute
|
||||||
|
- [x] **default**: defines the default function to init the field
|
||||||
- [ ] **flatten**: Flatten the contents of the field
|
- [ ] **flatten**: Flatten the contents of the field
|
||||||
- [x] **namespace**: defines the namespace of the field
|
- [x] **namespace**: defines the namespace of the field
|
||||||
- [x] **rename**: be able to rename a field
|
- [x] **rename**: be able to rename a field
|
||||||
|
|||||||
@@ -29,8 +29,7 @@ fn de_default_field_string() {
|
|||||||
background: String,
|
background: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
let content =
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?><base></base>";
|
|
||||||
convert_and_validate!(
|
convert_and_validate!(
|
||||||
content,
|
content,
|
||||||
XmlStruct,
|
XmlStruct,
|
||||||
@@ -53,15 +52,8 @@ fn de_default_field_boolean() {
|
|||||||
background: bool,
|
background: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
let content =
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?><base></base>";
|
convert_and_validate!(content, XmlStruct, XmlStruct { background: true });
|
||||||
convert_and_validate!(
|
|
||||||
content,
|
|
||||||
XmlStruct,
|
|
||||||
XmlStruct {
|
|
||||||
background: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -77,15 +69,8 @@ fn de_default_field_number() {
|
|||||||
background: u8,
|
background: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
let content =
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?><base></base>";
|
convert_and_validate!(content, XmlStruct, XmlStruct { background: 6 });
|
||||||
convert_and_validate!(
|
|
||||||
content,
|
|
||||||
XmlStruct,
|
|
||||||
XmlStruct {
|
|
||||||
background: 6,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -101,8 +86,7 @@ fn de_default_attribute_string() {
|
|||||||
background: String,
|
background: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
let content =
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?><base></base>";
|
|
||||||
convert_and_validate!(
|
convert_and_validate!(
|
||||||
content,
|
content,
|
||||||
XmlStruct,
|
XmlStruct,
|
||||||
|
|||||||
@@ -121,22 +121,28 @@ fn de_option() {
|
|||||||
fn de_option_struct() {
|
fn de_option_struct() {
|
||||||
#[derive(YaDeserialize, Debug, PartialEq)]
|
#[derive(YaDeserialize, Debug, PartialEq)]
|
||||||
struct Test {
|
struct Test {
|
||||||
field: SubTest
|
field: SubTest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(YaDeserialize, Debug, PartialEq)]
|
#[derive(YaDeserialize, Debug, PartialEq)]
|
||||||
struct SubTest {
|
struct SubTest {
|
||||||
content: Option<String>
|
content: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SubTest {
|
impl Default for SubTest {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
SubTest {
|
SubTest { content: None }
|
||||||
content: None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_and_validate!(Test, Some(Test{field: SubTest{content: Some("value".to_string())}}), Some("<field><content>value</content></field>"));
|
convert_and_validate!(
|
||||||
|
Test,
|
||||||
|
Some(Test {
|
||||||
|
field: SubTest {
|
||||||
|
content: Some("value".to_string())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Some("<field><content>value</content></field>")
|
||||||
|
);
|
||||||
convert_and_validate!(Test, None, None);
|
convert_and_validate!(Test, None, None);
|
||||||
}
|
}
|
||||||
|
|||||||
110
yaserde/tests/se_default.rs
Normal file
110
yaserde/tests/se_default.rs
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
extern crate xml;
|
||||||
|
extern crate yaserde;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate yaserde_derive;
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
|
use yaserde::ser::to_string;
|
||||||
|
use yaserde::YaSerialize;
|
||||||
|
|
||||||
|
macro_rules! convert_and_validate {
|
||||||
|
($model:expr, $content:expr) => {
|
||||||
|
let data: Result<String, String> = to_string(&$model);
|
||||||
|
assert_eq!(data, Ok(String::from($content)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn se_default_field_string() {
|
||||||
|
fn default_string() -> String {
|
||||||
|
"my_default_value".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
#[yaserde(root = "base")]
|
||||||
|
pub struct XmlStruct {
|
||||||
|
#[yaserde(default = "default_string")]
|
||||||
|
background: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
|
convert_and_validate!(
|
||||||
|
XmlStruct {
|
||||||
|
background: "my_default_value".to_string(),
|
||||||
|
},
|
||||||
|
content
|
||||||
|
);
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><background>my_value</background></base>";
|
||||||
|
convert_and_validate!(
|
||||||
|
XmlStruct {
|
||||||
|
background: "my_value".to_string(),
|
||||||
|
},
|
||||||
|
content
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn se_default_field_boolean() {
|
||||||
|
fn default_boolean() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
#[yaserde(root = "base")]
|
||||||
|
pub struct XmlStruct {
|
||||||
|
#[yaserde(default = "default_boolean")]
|
||||||
|
background: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
|
convert_and_validate!(XmlStruct { background: true }, content);
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><background>false</background></base>";
|
||||||
|
convert_and_validate!(
|
||||||
|
XmlStruct {
|
||||||
|
background: false,
|
||||||
|
},
|
||||||
|
content
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn se_default_field_number() {
|
||||||
|
fn default_number() -> u8 {
|
||||||
|
6
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
#[yaserde(root = "base")]
|
||||||
|
pub struct XmlStruct {
|
||||||
|
#[yaserde(default = "default_number")]
|
||||||
|
background: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
|
convert_and_validate!(XmlStruct { background: 6 }, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn se_default_attribute_string() {
|
||||||
|
fn default_string() -> String {
|
||||||
|
"my_default_value".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
#[yaserde(root = "base")]
|
||||||
|
pub struct XmlStruct {
|
||||||
|
#[yaserde(attribute, default = "default_string")]
|
||||||
|
background: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base />";
|
||||||
|
convert_and_validate!(
|
||||||
|
XmlStruct {
|
||||||
|
background: "my_default_value".to_string(),
|
||||||
|
},
|
||||||
|
content
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -124,22 +124,28 @@ fn ser_option() {
|
|||||||
fn de_option_struct() {
|
fn de_option_struct() {
|
||||||
#[derive(YaSerialize, Debug, PartialEq)]
|
#[derive(YaSerialize, Debug, PartialEq)]
|
||||||
struct Test {
|
struct Test {
|
||||||
field: SubTest
|
field: SubTest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(YaSerialize, Debug, PartialEq)]
|
#[derive(YaSerialize, Debug, PartialEq)]
|
||||||
struct SubTest {
|
struct SubTest {
|
||||||
content: Option<String>
|
content: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SubTest {
|
impl Default for SubTest {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
SubTest {
|
SubTest { content: None }
|
||||||
content: None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_and_validate!(Test, Some(Test{field: SubTest{content: Some("value".to_string())}}), Some("<field><content>value</content></field>"));
|
convert_and_validate!(
|
||||||
|
Test,
|
||||||
|
Some(Test {
|
||||||
|
field: SubTest {
|
||||||
|
content: Some("value".to_string())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Some("<field><content>value</content></field>")
|
||||||
|
);
|
||||||
convert_and_validate!(Test, None, None);
|
convert_and_validate!(Test, None, None);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,8 @@ fn parse_empty_attributes() {
|
|||||||
let attributes = vec![];
|
let attributes = vec![];
|
||||||
let attrs = YaSerdeAttribute::parse(&attributes);
|
let attrs = YaSerdeAttribute::parse(&attributes);
|
||||||
|
|
||||||
assert_eq!(YaSerdeAttribute {
|
assert_eq!(
|
||||||
|
YaSerdeAttribute {
|
||||||
root: None,
|
root: None,
|
||||||
rename: None,
|
rename: None,
|
||||||
prefix: None,
|
prefix: None,
|
||||||
@@ -112,45 +113,46 @@ fn parse_empty_attributes() {
|
|||||||
namespaces: BTreeMap::new(),
|
namespaces: BTreeMap::new(),
|
||||||
attribute: false,
|
attribute: false,
|
||||||
text: false,
|
text: false,
|
||||||
}, attrs);
|
},
|
||||||
|
attrs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_attributes() {
|
fn parse_attributes() {
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use syn::punctuated::Punctuated;
|
||||||
|
use syn::token::Bracket;
|
||||||
|
use syn::token::Pound;
|
||||||
use syn::AttrStyle::Outer;
|
use syn::AttrStyle::Outer;
|
||||||
use syn::{Ident, Path, PathArguments, PathSegment};
|
use syn::{Ident, Path, PathArguments, PathSegment};
|
||||||
use syn::token::Pound;
|
|
||||||
use syn::token::Bracket;
|
|
||||||
use syn::punctuated::Punctuated;
|
|
||||||
|
|
||||||
let mut punctuated = Punctuated::new();
|
let mut punctuated = Punctuated::new();
|
||||||
punctuated.push(PathSegment {
|
punctuated.push(PathSegment {
|
||||||
ident: Ident::new("yaserde", Span::call_site()),
|
ident: Ident::new("yaserde", Span::call_site()),
|
||||||
arguments: PathArguments::None
|
arguments: PathArguments::None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let attributes = vec![
|
let attributes = vec![Attribute {
|
||||||
Attribute {
|
|
||||||
pound_token: Pound {
|
pound_token: Pound {
|
||||||
spans: [Span::call_site()]
|
spans: [Span::call_site()],
|
||||||
},
|
},
|
||||||
style: Outer,
|
style: Outer,
|
||||||
bracket_token: Bracket {
|
bracket_token: Bracket {
|
||||||
span: Span::call_site()
|
span: Span::call_site(),
|
||||||
},
|
},
|
||||||
path: Path {
|
path: Path {
|
||||||
leading_colon: None,
|
leading_colon: None,
|
||||||
segments: punctuated
|
segments: punctuated,
|
||||||
},
|
},
|
||||||
tts: TokenStream::from_str("(attribute)").unwrap()
|
tts: TokenStream::from_str("(attribute)").unwrap(),
|
||||||
}
|
}];
|
||||||
];
|
|
||||||
|
|
||||||
let attrs = YaSerdeAttribute::parse(&attributes);
|
let attrs = YaSerdeAttribute::parse(&attributes);
|
||||||
|
|
||||||
assert_eq!(YaSerdeAttribute {
|
assert_eq!(
|
||||||
|
YaSerdeAttribute {
|
||||||
root: None,
|
root: None,
|
||||||
rename: None,
|
rename: None,
|
||||||
prefix: None,
|
prefix: None,
|
||||||
@@ -158,5 +160,7 @@ fn parse_attributes() {
|
|||||||
namespaces: BTreeMap::new(),
|
namespaces: BTreeMap::new(),
|
||||||
attribute: true,
|
attribute: true,
|
||||||
text: false,
|
text: false,
|
||||||
}, attrs);
|
},
|
||||||
|
attrs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
24
yaserde_derive/src/de/build_default_value.rs
Normal file
24
yaserde_derive/src/de/build_default_value.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
use proc_macro2::{Span, TokenStream};
|
||||||
|
use syn::Ident;
|
||||||
|
|
||||||
|
pub fn build_default_value(
|
||||||
|
label: &Option<Ident>,
|
||||||
|
field_type: &TokenStream,
|
||||||
|
value: &TokenStream,
|
||||||
|
default: &Option<String>,
|
||||||
|
) -> Option<TokenStream> {
|
||||||
|
if let Some(d) = default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut #label : #field_type = #default_function();
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut #label : #field_type = #value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ use std::collections::BTreeMap;
|
|||||||
use syn::DataEnum;
|
use syn::DataEnum;
|
||||||
use syn::Fields;
|
use syn::Fields;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
use de::build_default_value::build_default_value;
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
data_enum: &DataEnum,
|
data_enum: &DataEnum,
|
||||||
@@ -24,95 +25,111 @@ pub fn parse(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let field_label = &field.ident;
|
let field_label = &field.ident;
|
||||||
|
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||||
|
|
||||||
match get_field_type(field) {
|
match get_field_type(field) {
|
||||||
Some(FieldType::FieldTypeString) => {
|
Some(FieldType::FieldTypeString) => {
|
||||||
build_default_value(field_label, "e!{String}, "e!{"".to_string()})
|
build_default_value(field_label, "e! {String}, "e! {"".to_string()}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeBool) => {
|
Some(FieldType::FieldTypeBool) => {
|
||||||
build_default_value(field_label, "e!{bool}, "e!{false})
|
build_default_value(field_label, "e! {bool}, "e! {false}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeI8) => {
|
Some(FieldType::FieldTypeI8) => {
|
||||||
build_default_value(field_label, "e!{i8}, "e!{0})
|
build_default_value(field_label, "e! {i8}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeU8) => {
|
Some(FieldType::FieldTypeU8) => {
|
||||||
build_default_value(field_label, "e!{u8}, "e!{0})
|
build_default_value(field_label, "e! {u8}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeI16) => {
|
Some(FieldType::FieldTypeI16) => {
|
||||||
build_default_value(field_label, "e!{i16}, "e!{0})
|
build_default_value(field_label, "e! {i16}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeU16) => {
|
Some(FieldType::FieldTypeU16) => {
|
||||||
build_default_value(field_label, "e!{u16}, "e!{0})
|
build_default_value(field_label, "e! {u16}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeI32) => {
|
Some(FieldType::FieldTypeI32) => {
|
||||||
build_default_value(field_label, "e!{i32}, "e!{0})
|
build_default_value(field_label, "e! {i32}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeU32) => {
|
Some(FieldType::FieldTypeU32) => {
|
||||||
build_default_value(field_label, "e!{u32}, "e!{0})
|
build_default_value(field_label, "e! {u32}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeI64) => {
|
Some(FieldType::FieldTypeI64) => {
|
||||||
build_default_value(field_label, "e!{i64}, "e!{0})
|
build_default_value(field_label, "e! {i64}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeU64) => {
|
Some(FieldType::FieldTypeU64) => {
|
||||||
build_default_value(field_label, "e!{u64}, "e!{0})
|
build_default_value(field_label, "e! {u64}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeF32) => {
|
Some(FieldType::FieldTypeF32) => {
|
||||||
build_default_value(field_label, "e!{f32}, "e!{0})
|
build_default_value(field_label, "e! {f32}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeF64) => {
|
Some(FieldType::FieldTypeF64) => {
|
||||||
build_default_value(field_label, "e!{f64}, "e!{0})
|
build_default_value(field_label, "e! {f64}, "e! {0}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeStruct { struct_name }) => Some(quote!{
|
Some(FieldType::FieldTypeStruct { struct_name }) => build_default_value(
|
||||||
#[allow(unused_mut)]
|
field_label,
|
||||||
let mut #field_label : #struct_name = #struct_name::default();
|
"e! {#struct_name},
|
||||||
}),
|
"e! {#struct_name::default()},
|
||||||
Some(FieldType::FieldTypeOption { .. }) => Some(quote!{
|
&field_attrs.default,
|
||||||
#[allow(unused_mut)]
|
),
|
||||||
|
Some(FieldType::FieldTypeOption { .. }) => {
|
||||||
|
if let Some(d) = &field_attrs.default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
#[allow(unused_mut, non_snake_case, non_camel_case_types)]
|
||||||
|
let mut #field_label = #default_function();
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
#[allow(unused_mut, non_snake_case, non_camel_case_types)]
|
||||||
let mut #field_label = None;
|
let mut #field_label = None;
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Some(FieldType::FieldTypeVec { data_type }) => {
|
Some(FieldType::FieldTypeVec { data_type }) => {
|
||||||
let dt = Box::into_raw(data_type);
|
let dt = Box::into_raw(data_type);
|
||||||
match unsafe { dt.as_ref() } {
|
match unsafe { dt.as_ref() } {
|
||||||
Some(&FieldType::FieldTypeString) => {
|
Some(&FieldType::FieldTypeString) => {
|
||||||
build_default_value(field_label, "e!{Vec<String>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<String>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeBool) => {
|
Some(&FieldType::FieldTypeBool) => {
|
||||||
build_default_value(field_label, "e!{Vec<bool>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<bool>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeI8) => {
|
Some(&FieldType::FieldTypeI8) => {
|
||||||
build_default_value(field_label, "e!{Vec<i8>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<i8>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeU8) => {
|
Some(&FieldType::FieldTypeU8) => {
|
||||||
build_default_value(field_label, "e!{Vec<u8>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<u8>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeI16) => {
|
Some(&FieldType::FieldTypeI16) => {
|
||||||
build_default_value(field_label, "e!{Vec<i16>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<i16>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeU16) => {
|
Some(&FieldType::FieldTypeU16) => {
|
||||||
build_default_value(field_label, "e!{Vec<u16>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<u16>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeI32) => {
|
Some(&FieldType::FieldTypeI32) => {
|
||||||
build_default_value(field_label, "e!{Vec<i32>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<i32>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeU32) => {
|
Some(&FieldType::FieldTypeU32) => {
|
||||||
build_default_value(field_label, "e!{Vec<u32>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<u32>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeI64) => {
|
Some(&FieldType::FieldTypeI64) => {
|
||||||
build_default_value(field_label, "e!{Vec<i64>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<i64>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeU64) => {
|
Some(&FieldType::FieldTypeU64) => {
|
||||||
build_default_value(field_label, "e!{Vec<u64>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<u64>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeF32) => {
|
Some(&FieldType::FieldTypeF32) => {
|
||||||
build_default_value(field_label, "e!{Vec<f32>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<f32>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeF64) => {
|
Some(&FieldType::FieldTypeF64) => {
|
||||||
build_default_value(field_label, "e!{Vec<f64>}, "e!{vec![]})
|
build_default_value(field_label, "e! {Vec<f64>}, "e! {vec![]}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(&FieldType::FieldTypeStruct { ref struct_name }) => Some(quote!{
|
Some(&FieldType::FieldTypeStruct { ref struct_name }) => build_default_value(
|
||||||
#[allow(unused_mut)]
|
field_label,
|
||||||
let mut #field_label : Vec<#struct_name> = vec![];
|
"e! {Vec<#struct_name>},
|
||||||
}),
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
Some(&FieldType::FieldTypeOption { .. })
|
Some(&FieldType::FieldTypeOption { .. })
|
||||||
| Some(&FieldType::FieldTypeVec { .. }) => {
|
| Some(&FieldType::FieldTypeVec { .. }) => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
@@ -232,14 +249,3 @@ pub fn parse(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_default_value(
|
|
||||||
label: &Option<Ident>,
|
|
||||||
field_type: &TokenStream,
|
|
||||||
default: &TokenStream,
|
|
||||||
) -> Option<TokenStream> {
|
|
||||||
Some(quote!{
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
let mut #label : #field_type = #default;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use quote::TokenStreamExt;
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use syn::DataStruct;
|
use syn::DataStruct;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
use de::build_default_value::build_default_value;
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
data_struct: &DataStruct,
|
data_struct: &DataStruct,
|
||||||
@@ -43,23 +44,51 @@ pub fn parse(
|
|||||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||||
|
|
||||||
match get_field_type(field) {
|
match get_field_type(field) {
|
||||||
Some(FieldType::FieldTypeString) => {
|
Some(FieldType::FieldTypeString) => build_default_value(
|
||||||
build_default_value(label, "e!{String}, "e!{"".to_string()}, &field_attrs.default)
|
label,
|
||||||
|
"e! {String},
|
||||||
|
"e! {"".to_string()},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
|
Some(FieldType::FieldTypeBool) => {
|
||||||
|
build_default_value(label, "e! {bool}, "e! {false}, &field_attrs.default)
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeBool) => build_default_value(label, "e!{bool}, "e!{false}, &field_attrs.default),
|
Some(FieldType::FieldTypeI8) => {
|
||||||
Some(FieldType::FieldTypeI8) => build_default_value(label, "e!{i8}, "e!{0}, &field_attrs.default),
|
build_default_value(label, "e! {i8}, "e! {0}, &field_attrs.default)
|
||||||
Some(FieldType::FieldTypeU8) => build_default_value(label, "e!{u8}, "e!{0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeI16) => build_default_value(label, "e!{i16}, "e!{0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeU16) => build_default_value(label, "e!{u16}, "e!{0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeI32) => build_default_value(label, "e!{i32}, "e!{0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeU32) => build_default_value(label, "e!{u32}, "e!{0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeI64) => build_default_value(label, "e!{i64}, "e!{0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeU64) => build_default_value(label, "e!{u64}, "e!{0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeF32) => build_default_value(label, "e!{f32}, "e!{0.0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeF64) => build_default_value(label, "e!{f64}, "e!{0.0}, &field_attrs.default),
|
|
||||||
Some(FieldType::FieldTypeStruct { struct_name }) => {
|
|
||||||
build_default_value(label, "e!{#struct_name}, "e!{#struct_name::default()}, &field_attrs.default)
|
|
||||||
}
|
}
|
||||||
|
Some(FieldType::FieldTypeU8) => {
|
||||||
|
build_default_value(label, "e! {u8}, "e! {0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeI16) => {
|
||||||
|
build_default_value(label, "e! {i16}, "e! {0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeU16) => {
|
||||||
|
build_default_value(label, "e! {u16}, "e! {0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeI32) => {
|
||||||
|
build_default_value(label, "e! {i32}, "e! {0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeU32) => {
|
||||||
|
build_default_value(label, "e! {u32}, "e! {0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeI64) => {
|
||||||
|
build_default_value(label, "e! {i64}, "e! {0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeU64) => {
|
||||||
|
build_default_value(label, "e! {u64}, "e! {0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeF32) => {
|
||||||
|
build_default_value(label, "e! {f32}, "e! {0.0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeF64) => {
|
||||||
|
build_default_value(label, "e! {f64}, "e! {0.0}, &field_attrs.default)
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeStruct { struct_name }) => build_default_value(
|
||||||
|
label,
|
||||||
|
"e! {#struct_name},
|
||||||
|
"e! {#struct_name::default()},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
Some(FieldType::FieldTypeOption { .. }) => {
|
Some(FieldType::FieldTypeOption { .. }) => {
|
||||||
if let Some(d) = &field_attrs.default {
|
if let Some(d) = &field_attrs.default {
|
||||||
let default_function = Ident::new(&d, Span::call_site());
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
@@ -78,45 +107,84 @@ pub fn parse(
|
|||||||
Some(FieldType::FieldTypeVec { data_type }) => {
|
Some(FieldType::FieldTypeVec { data_type }) => {
|
||||||
let dt = Box::into_raw(data_type);
|
let dt = Box::into_raw(data_type);
|
||||||
match unsafe { dt.as_ref() } {
|
match unsafe { dt.as_ref() } {
|
||||||
Some(&FieldType::FieldTypeString) => {
|
Some(&FieldType::FieldTypeString) => build_default_value(
|
||||||
build_default_value(label, "e!{Vec<String>}, "e!{vec![]}, &field_attrs.default)
|
label,
|
||||||
}
|
"e! {Vec<String>},
|
||||||
Some(&FieldType::FieldTypeBool) => {
|
"e! {vec![]},
|
||||||
build_default_value(label, "e!{Vec<bool>}, "e!{vec![]}, &field_attrs.default)
|
&field_attrs.default,
|
||||||
}
|
),
|
||||||
Some(&FieldType::FieldTypeI8) => {
|
Some(&FieldType::FieldTypeBool) => build_default_value(
|
||||||
build_default_value(label, "e!{Vec<i8>}, "e!{vec![]}, &field_attrs.default)
|
label,
|
||||||
}
|
"e! {Vec<bool>},
|
||||||
Some(&FieldType::FieldTypeU8) => {
|
"e! {vec![]},
|
||||||
build_default_value(label, "e!{Vec<u8>}, "e!{vec![]}, &field_attrs.default)
|
&field_attrs.default,
|
||||||
}
|
),
|
||||||
Some(&FieldType::FieldTypeI16) => {
|
Some(&FieldType::FieldTypeI8) => build_default_value(
|
||||||
build_default_value(label, "e!{Vec<i16>}, "e!{vec![]}, &field_attrs.default)
|
label,
|
||||||
}
|
"e! {Vec<i8>},
|
||||||
Some(&FieldType::FieldTypeU16) => {
|
"e! {vec![]},
|
||||||
build_default_value(label, "e!{Vec<u16>}, "e!{vec![]}, &field_attrs.default)
|
&field_attrs.default,
|
||||||
}
|
),
|
||||||
Some(&FieldType::FieldTypeI32) => {
|
Some(&FieldType::FieldTypeU8) => build_default_value(
|
||||||
build_default_value(label, "e!{Vec<i32>}, "e!{vec![]}, &field_attrs.default)
|
label,
|
||||||
}
|
"e! {Vec<u8>},
|
||||||
Some(&FieldType::FieldTypeU32) => {
|
"e! {vec![]},
|
||||||
build_default_value(label, "e!{Vec<u32>}, "e!{vec![]}, &field_attrs.default)
|
&field_attrs.default,
|
||||||
}
|
),
|
||||||
Some(&FieldType::FieldTypeI64) => {
|
Some(&FieldType::FieldTypeI16) => build_default_value(
|
||||||
build_default_value(label, "e!{Vec<i64>}, "e!{vec![]}, &field_attrs.default)
|
label,
|
||||||
}
|
"e! {Vec<i16>},
|
||||||
Some(&FieldType::FieldTypeU64) => {
|
"e! {vec![]},
|
||||||
build_default_value(label, "e!{Vec<u64>}, "e!{vec![]}, &field_attrs.default)
|
&field_attrs.default,
|
||||||
}
|
),
|
||||||
Some(&FieldType::FieldTypeF32) => {
|
Some(&FieldType::FieldTypeU16) => build_default_value(
|
||||||
build_default_value(label, "e!{Vec<f32>}, "e!{vec![]}, &field_attrs.default)
|
label,
|
||||||
}
|
"e! {Vec<u16>},
|
||||||
Some(&FieldType::FieldTypeF64) => {
|
"e! {vec![]},
|
||||||
build_default_value(label, "e!{Vec<f64>}, "e!{vec![]}, &field_attrs.default)
|
&field_attrs.default,
|
||||||
}
|
),
|
||||||
Some(&FieldType::FieldTypeStruct { ref struct_name }) => {
|
Some(&FieldType::FieldTypeI32) => build_default_value(
|
||||||
build_default_value(label, "e!{Vec<#struct_name>}, "e!{vec![]}, &field_attrs.default)
|
label,
|
||||||
}
|
"e! {Vec<i32>},
|
||||||
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
|
Some(&FieldType::FieldTypeU32) => build_default_value(
|
||||||
|
label,
|
||||||
|
"e! {Vec<u32>},
|
||||||
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
|
Some(&FieldType::FieldTypeI64) => build_default_value(
|
||||||
|
label,
|
||||||
|
"e! {Vec<i64>},
|
||||||
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
|
Some(&FieldType::FieldTypeU64) => build_default_value(
|
||||||
|
label,
|
||||||
|
"e! {Vec<u64>},
|
||||||
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
|
Some(&FieldType::FieldTypeF32) => build_default_value(
|
||||||
|
label,
|
||||||
|
"e! {Vec<f32>},
|
||||||
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
|
Some(&FieldType::FieldTypeF64) => build_default_value(
|
||||||
|
label,
|
||||||
|
"e! {Vec<f64>},
|
||||||
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
|
Some(&FieldType::FieldTypeStruct { ref struct_name }) => build_default_value(
|
||||||
|
label,
|
||||||
|
"e! {Vec<#struct_name>},
|
||||||
|
"e! {vec![]},
|
||||||
|
&field_attrs.default,
|
||||||
|
),
|
||||||
Some(&FieldType::FieldTypeOption { .. }) | Some(&FieldType::FieldTypeVec { .. }) => {
|
Some(&FieldType::FieldTypeOption { .. }) | Some(&FieldType::FieldTypeVec { .. }) => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
@@ -1189,27 +1257,6 @@ pub fn parse(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_default_value(
|
|
||||||
label: &Option<Ident>,
|
|
||||||
field_type: &TokenStream,
|
|
||||||
value: &TokenStream,
|
|
||||||
default: &Option<String>,
|
|
||||||
) -> Option<TokenStream> {
|
|
||||||
if let Some(d) = default {
|
|
||||||
let default_function = Ident::new(&d, Span::call_site());
|
|
||||||
|
|
||||||
Some(quote!{
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
let mut #label : #field_type = #default_function();
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Some(quote!{
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
let mut #label : #field_type = #value;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_declare_visitor(
|
fn build_declare_visitor(
|
||||||
field_type: &TokenStream,
|
field_type: &TokenStream,
|
||||||
visitor: &TokenStream,
|
visitor: &TokenStream,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
pub mod build_default_value;
|
||||||
pub mod expand_enum;
|
pub mod expand_enum;
|
||||||
pub mod expand_struct;
|
pub mod expand_struct;
|
||||||
|
|
||||||
|
|||||||
75
yaserde_derive/src/ser/element.rs
Normal file
75
yaserde_derive/src/ser/element.rs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
use proc_macro2::{Ident, Span, TokenStream};
|
||||||
|
|
||||||
|
|
||||||
|
pub fn enclose_formatted_characters(
|
||||||
|
label: &Ident,
|
||||||
|
label_name: String
|
||||||
|
) -> TokenStream {
|
||||||
|
quote! {
|
||||||
|
let start_event = XmlEvent::start_element(#label_name);
|
||||||
|
let _ret = writer.write(start_event);
|
||||||
|
|
||||||
|
let yas_value = format!("{}", &self.#label);
|
||||||
|
let data_event = XmlEvent::characters(&yas_value);
|
||||||
|
let _ret = writer.write(data_event);
|
||||||
|
|
||||||
|
let end_event = XmlEvent::end_element();
|
||||||
|
let _ret = writer.write(end_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enclose_formatted_characters_for_value(
|
||||||
|
label: &Ident,
|
||||||
|
label_name: String
|
||||||
|
) -> TokenStream {
|
||||||
|
quote! {
|
||||||
|
let start_event = XmlEvent::start_element(#label_name);
|
||||||
|
let _ret = writer.write(start_event);
|
||||||
|
|
||||||
|
let value = format!("{}", #label);
|
||||||
|
let data_event = XmlEvent::characters(&value);
|
||||||
|
let _ret = writer.write(data_event);
|
||||||
|
|
||||||
|
let end_event = XmlEvent::end_element();
|
||||||
|
let _ret = writer.write(end_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enclose_characters(
|
||||||
|
label: &Option<Ident>,
|
||||||
|
label_name: String
|
||||||
|
) -> TokenStream {
|
||||||
|
quote! {
|
||||||
|
let start_event = XmlEvent::start_element(#label_name);
|
||||||
|
let _ret = writer.write(start_event);
|
||||||
|
|
||||||
|
let value = format!("{}", self.#label);
|
||||||
|
let data_event = XmlEvent::characters(&value);
|
||||||
|
let _ret = writer.write(data_event);
|
||||||
|
|
||||||
|
let end_event = XmlEvent::end_element();
|
||||||
|
let _ret = writer.write(end_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize_element(
|
||||||
|
label: &Option<Ident>,
|
||||||
|
label_name: String,
|
||||||
|
default: &Option<String>,
|
||||||
|
) -> Option<TokenStream> {
|
||||||
|
let inner = enclose_characters(label, label_name);
|
||||||
|
|
||||||
|
if let Some(ref d) = default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
Some(quote! {
|
||||||
|
if self.#label != #default_function() {
|
||||||
|
#inner
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
#inner
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ use std::string::ToString;
|
|||||||
use syn::DataStruct;
|
use syn::DataStruct;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
|
||||||
|
use ser::element::*;
|
||||||
|
|
||||||
pub fn serialize(
|
pub fn serialize(
|
||||||
data_struct: &DataStruct,
|
data_struct: &DataStruct,
|
||||||
name: &Ident,
|
name: &Ident,
|
||||||
@@ -45,7 +47,27 @@ pub fn serialize(
|
|||||||
| Some(FieldType::FieldTypeI64)
|
| Some(FieldType::FieldTypeI64)
|
||||||
| Some(FieldType::FieldTypeU64)
|
| Some(FieldType::FieldTypeU64)
|
||||||
| Some(FieldType::FieldTypeF32)
|
| Some(FieldType::FieldTypeF32)
|
||||||
| Some(FieldType::FieldTypeF64) => Some(quote!{
|
| Some(FieldType::FieldTypeF64) => {
|
||||||
|
if let Some(ref d) = field_attrs.default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
Some(quote! {
|
||||||
|
let struct_start_event =
|
||||||
|
if self.#label != #default_function() {
|
||||||
|
struct_start_event.attr(#label_name, &*{
|
||||||
|
use std::mem;
|
||||||
|
unsafe {
|
||||||
|
let content = format!("{}", self.#label);
|
||||||
|
let ret : &'static str = mem::transmute(&content as &str);
|
||||||
|
mem::forget(content);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
struct_start_event
|
||||||
|
};
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
let struct_start_event = struct_start_event.attr(#label_name, &*{
|
let struct_start_event = struct_start_event.attr(#label_name, &*{
|
||||||
use std::mem;
|
use std::mem;
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -55,18 +77,38 @@ pub fn serialize(
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
Some(FieldType::FieldTypeOption { data_type }) => {
|
Some(FieldType::FieldTypeOption { data_type }) => {
|
||||||
let dt = Box::into_raw(data_type);
|
let dt = Box::into_raw(data_type);
|
||||||
match unsafe { dt.as_ref() } {
|
match unsafe { dt.as_ref() } {
|
||||||
Some(&FieldType::FieldTypeString) => Some(quote!{
|
Some(&FieldType::FieldTypeString) => {
|
||||||
|
if let Some(ref d) = field_attrs.default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
Some(quote! {
|
||||||
|
let struct_start_event =
|
||||||
|
if self.#label != #default_function() {
|
||||||
|
if let Some(ref value) = self.#label {
|
||||||
|
struct_start_event.attr(#label_name, &value)
|
||||||
|
} else {
|
||||||
|
struct_start_event
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct_start_event
|
||||||
|
};
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
let struct_start_event =
|
let struct_start_event =
|
||||||
if let Some(ref value) = self.#label {
|
if let 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
|
||||||
};
|
};
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
Some(&FieldType::FieldTypeBool)
|
Some(&FieldType::FieldTypeBool)
|
||||||
| Some(&FieldType::FieldTypeI8)
|
| Some(&FieldType::FieldTypeI8)
|
||||||
| Some(&FieldType::FieldTypeU8)
|
| Some(&FieldType::FieldTypeU8)
|
||||||
@@ -77,9 +119,33 @@ pub fn serialize(
|
|||||||
| Some(&FieldType::FieldTypeI64)
|
| Some(&FieldType::FieldTypeI64)
|
||||||
| Some(&FieldType::FieldTypeU64)
|
| Some(&FieldType::FieldTypeU64)
|
||||||
| Some(&FieldType::FieldTypeF32)
|
| Some(&FieldType::FieldTypeF32)
|
||||||
| Some(&FieldType::FieldTypeF64) => Some(quote!{
|
| Some(&FieldType::FieldTypeF64) => {
|
||||||
|
if let Some(ref d) = field_attrs.default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
Some(quote! {
|
||||||
let struct_start_event =
|
let struct_start_event =
|
||||||
if let Some(value) = self.#label {
|
if self.#label != #default_function() {
|
||||||
|
if let Some(ref value) = self.#label {
|
||||||
|
struct_start_event.attr(#label_name, &*{
|
||||||
|
use std::mem;
|
||||||
|
unsafe {
|
||||||
|
let content = format!("{}", value);
|
||||||
|
let ret : &'static str = mem::transmute(&content as &str);
|
||||||
|
mem::forget(content);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
struct_start_event
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct_start_event
|
||||||
|
};
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
let struct_start_event =
|
||||||
|
if let Some(ref value) = self.#label {
|
||||||
struct_start_event.attr(#label_name, &*{
|
struct_start_event.attr(#label_name, &*{
|
||||||
use std::mem;
|
use std::mem;
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -92,23 +158,61 @@ pub fn serialize(
|
|||||||
} else {
|
} else {
|
||||||
struct_start_event
|
struct_start_event
|
||||||
};
|
};
|
||||||
}),
|
})
|
||||||
Some(&FieldType::FieldTypeVec { .. }) => Some(quote!{
|
|
||||||
for item in &self.#label {
|
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let data_event = XmlEvent::characters(item);
|
|
||||||
let _ret = writer.write(data_event);
|
|
||||||
|
|
||||||
let end_event = XmlEvent::end_element();
|
|
||||||
let _ret = writer.write(end_event);
|
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
|
Some(&FieldType::FieldTypeVec { .. }) => {
|
||||||
|
let item_ident = Ident::new("yas_item", Span::call_site());
|
||||||
|
let inner = enclose_formatted_characters(&item_ident, label_name);
|
||||||
|
|
||||||
|
if let Some(ref d) = field_attrs.default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
if self.#label != #default_function() {
|
||||||
|
if let Some(ref yas_list) = self.#label {
|
||||||
|
for yas_item in yas_list.iter() {
|
||||||
|
#inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
for yas_item in &self.#label {
|
||||||
|
#inner
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{
|
Some(FieldType::FieldTypeStruct { .. }) => {
|
||||||
|
if let Some(ref d) = field_attrs.default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
Some(quote! {
|
||||||
|
let struct_start_event =
|
||||||
|
if self.#label != #default_function() {
|
||||||
|
struct_start_event.attr(#label_name, &*{
|
||||||
|
use std::mem;
|
||||||
|
match yaserde::ser::to_string_content(&self.#label) {
|
||||||
|
Ok(value) => {
|
||||||
|
unsafe {
|
||||||
|
let ret : &'static str = mem::transmute(&value as &str);
|
||||||
|
mem::forget(value);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(msg) => return Err("Unable to serialize content".to_owned()),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
struct_start_event
|
||||||
|
};
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
let struct_start_event = struct_start_event.attr(#label_name, &*{
|
let struct_start_event = struct_start_event.attr(#label_name, &*{
|
||||||
use std::mem;
|
use std::mem;
|
||||||
match yaserde::ser::to_string_content(&self.#label) {
|
match yaserde::ser::to_string_content(&self.#label) {
|
||||||
@@ -122,7 +226,9 @@ pub fn serialize(
|
|||||||
Err(msg) => return Err("Unable to serialize content".to_owned()),
|
Err(msg) => return Err("Unable to serialize content".to_owned()),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -176,17 +282,8 @@ pub fn serialize(
|
|||||||
};
|
};
|
||||||
|
|
||||||
match get_field_type(field) {
|
match get_field_type(field) {
|
||||||
Some(FieldType::FieldTypeString) => Some(quote!{
|
Some(FieldType::FieldTypeString)
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
| Some(FieldType::FieldTypeBool)
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let data_event = XmlEvent::characters(&self.#label);
|
|
||||||
let _ret = writer.write(data_event);
|
|
||||||
|
|
||||||
let end_event = XmlEvent::end_element();
|
|
||||||
let _ret = writer.write(end_event);
|
|
||||||
}),
|
|
||||||
Some(FieldType::FieldTypeBool)
|
|
||||||
| Some(FieldType::FieldTypeI8)
|
| Some(FieldType::FieldTypeI8)
|
||||||
| Some(FieldType::FieldTypeU8)
|
| Some(FieldType::FieldTypeU8)
|
||||||
| Some(FieldType::FieldTypeI16)
|
| Some(FieldType::FieldTypeI16)
|
||||||
@@ -196,33 +293,13 @@ pub fn serialize(
|
|||||||
| Some(FieldType::FieldTypeI64)
|
| Some(FieldType::FieldTypeI64)
|
||||||
| Some(FieldType::FieldTypeU64)
|
| Some(FieldType::FieldTypeU64)
|
||||||
| Some(FieldType::FieldTypeF32)
|
| Some(FieldType::FieldTypeF32)
|
||||||
| Some(FieldType::FieldTypeF64) => Some(quote!{
|
| Some(FieldType::FieldTypeF64) =>
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
serialize_element(label, label_name, &field_attrs.default),
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let content = format!("{}", &self.#label);
|
|
||||||
let data_event = XmlEvent::characters(&content);
|
|
||||||
let _ret = writer.write(data_event);
|
|
||||||
|
|
||||||
let end_event = XmlEvent::end_element();
|
|
||||||
let _ret = writer.write(end_event);
|
|
||||||
}),
|
|
||||||
Some(FieldType::FieldTypeOption { data_type }) => {
|
Some(FieldType::FieldTypeOption { data_type }) => {
|
||||||
let dt = Box::into_raw(data_type);
|
let dt = Box::into_raw(data_type);
|
||||||
match unsafe { dt.as_ref() } {
|
match unsafe { dt.as_ref() } {
|
||||||
Some(&FieldType::FieldTypeString) => Some(quote!{
|
Some(&FieldType::FieldTypeString)
|
||||||
if let Some(ref item) = self.#label {
|
| Some(&FieldType::FieldTypeBool)
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let data_event = XmlEvent::characters(&item);
|
|
||||||
let _ret = writer.write(data_event);
|
|
||||||
|
|
||||||
let end_event = XmlEvent::end_element();
|
|
||||||
let _ret = writer.write(end_event);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
Some(&FieldType::FieldTypeBool)
|
|
||||||
| Some(&FieldType::FieldTypeI8)
|
| Some(&FieldType::FieldTypeI8)
|
||||||
| Some(&FieldType::FieldTypeU8)
|
| Some(&FieldType::FieldTypeU8)
|
||||||
| Some(&FieldType::FieldTypeI16)
|
| Some(&FieldType::FieldTypeI16)
|
||||||
@@ -232,34 +309,54 @@ pub fn serialize(
|
|||||||
| Some(&FieldType::FieldTypeI64)
|
| Some(&FieldType::FieldTypeI64)
|
||||||
| Some(&FieldType::FieldTypeU64)
|
| Some(&FieldType::FieldTypeU64)
|
||||||
| Some(&FieldType::FieldTypeF32)
|
| Some(&FieldType::FieldTypeF32)
|
||||||
| Some(&FieldType::FieldTypeF64) => Some(quote!{
|
| Some(&FieldType::FieldTypeF64) => {
|
||||||
if let Some(item) = self.#label {
|
let item_ident = Ident::new("yas_item", Span::call_site());
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let content = format!("{}", item);
|
if let Some(ref d) = field_attrs.default {
|
||||||
let data_event = XmlEvent::characters(&content);
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
let _ret = writer.write(data_event);
|
|
||||||
|
|
||||||
let end_event = XmlEvent::end_element();
|
Some(quote! {
|
||||||
let _ret = writer.write(end_event);
|
if self.#label != #default_function() {
|
||||||
}
|
if let Some(ref yas_item) = self.#label {
|
||||||
}),
|
#inner
|
||||||
Some(&FieldType::FieldTypeVec { .. }) => Some(quote!{
|
|
||||||
if let Some(ref items) = &self.#label {
|
|
||||||
for item in items.iter() {
|
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let value = format!("{}", item);
|
|
||||||
let data_event = XmlEvent::characters(&value);
|
|
||||||
let _ret = writer.write(data_event);
|
|
||||||
|
|
||||||
let end_event = XmlEvent::end_element();
|
|
||||||
let _ret = writer.write(end_event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
if let Some(ref yas_item) = self.#label {
|
||||||
|
#inner
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(&FieldType::FieldTypeVec { .. }) => {
|
||||||
|
let item_ident = Ident::new("yas_item", Span::call_site());
|
||||||
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
|
|
||||||
|
if let Some(ref d) = field_attrs.default {
|
||||||
|
let default_function = Ident::new(&d, Span::call_site());
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
if self.#label != #default_function() {
|
||||||
|
if let Some(ref yas_items) = &self.#label {
|
||||||
|
for yas_item in yas_items.iter() {
|
||||||
|
#inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
if let Some(ref yas_items) = &self.#label {
|
||||||
|
for yas_item in yas_items.iter() {
|
||||||
|
#inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
Some(&FieldType::FieldTypeStruct { .. }) => Some(quote! {
|
Some(&FieldType::FieldTypeStruct { .. }) => Some(quote! {
|
||||||
if let Some(ref item) = &self.#label {
|
if let Some(ref item) = &self.#label {
|
||||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
writer.set_start_event_name(Some(#label_name.to_string()));
|
||||||
@@ -310,18 +407,16 @@ pub fn serialize(
|
|||||||
Some(FieldType::FieldTypeVec { data_type }) => {
|
Some(FieldType::FieldTypeVec { data_type }) => {
|
||||||
let dt = Box::into_raw(data_type);
|
let dt = Box::into_raw(data_type);
|
||||||
match unsafe { dt.as_ref() } {
|
match unsafe { dt.as_ref() } {
|
||||||
Some(&FieldType::FieldTypeString) => Some(quote!{
|
Some(&FieldType::FieldTypeString) => {
|
||||||
for item in &self.#label {
|
let item_ident = Ident::new("yas_item", Span::call_site());
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let data_event = XmlEvent::characters(item);
|
Some(quote! {
|
||||||
let _ret = writer.write(data_event);
|
for yas_item in &self.#label {
|
||||||
|
#inner
|
||||||
let end_event = XmlEvent::end_element();
|
|
||||||
let _ret = writer.write(end_event);
|
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
},
|
||||||
Some(&FieldType::FieldTypeBool)
|
Some(&FieldType::FieldTypeBool)
|
||||||
| Some(&FieldType::FieldTypeI8)
|
| Some(&FieldType::FieldTypeI8)
|
||||||
| Some(&FieldType::FieldTypeU8)
|
| Some(&FieldType::FieldTypeU8)
|
||||||
@@ -332,18 +427,16 @@ pub fn serialize(
|
|||||||
| Some(&FieldType::FieldTypeI64)
|
| Some(&FieldType::FieldTypeI64)
|
||||||
| Some(&FieldType::FieldTypeU64)
|
| Some(&FieldType::FieldTypeU64)
|
||||||
| Some(&FieldType::FieldTypeF32)
|
| Some(&FieldType::FieldTypeF32)
|
||||||
| Some(&FieldType::FieldTypeF64) => Some(quote!{
|
| Some(&FieldType::FieldTypeF64) => {
|
||||||
for item in &self.#label {
|
let item_ident = Ident::new("yas_item", Span::call_site());
|
||||||
let start_event = XmlEvent::start_element(#label_name);
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
let _ret = writer.write(start_event);
|
|
||||||
|
|
||||||
let data_event = XmlEvent::characters(format!("{}", item));
|
Some(quote! {
|
||||||
let _ret = writer.write(data_event);
|
for yas_item in &self.#label {
|
||||||
|
#inner
|
||||||
let end_event = XmlEvent::end_element();
|
|
||||||
let _ret = writer.write(end_event);
|
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
},
|
||||||
Some(&FieldType::FieldTypeOption { .. }) => Some(quote! {
|
Some(&FieldType::FieldTypeOption { .. }) => Some(quote! {
|
||||||
for item in &self.#label {
|
for item in &self.#label {
|
||||||
if let Some(value) = item {
|
if let Some(value) = item {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
pub mod element;
|
||||||
pub mod expand_enum;
|
pub mod expand_enum;
|
||||||
pub mod expand_struct;
|
pub mod expand_struct;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user