From 0fd06404daec5b1cec5e2c94b84d342f2e41bbde Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Mon, 20 Apr 2020 22:23:12 +0200 Subject: [PATCH 1/7] start to restructure unit tests --- yaserde/src/lib.rs | 73 ++++++++++++++++ yaserde/tests/de_default.rs | 93 --------------------- yaserde/tests/de_option.rs | 144 -------------------------------- yaserde/tests/de_type.rs | 81 ------------------ yaserde/tests/default.rs | 113 +++++++++++++++++++++++++ yaserde/tests/flatten.rs | 145 ++++++++++++++++++++++++++++++++ yaserde/tests/option.rs | 103 +++++++++++++++++++++++ yaserde/tests/ser_default.rs | 103 ----------------------- yaserde/tests/ser_enum.rs | 86 ++++++++----------- yaserde/tests/ser_flatten.rs | 35 ++------ yaserde/tests/ser_namespace.rs | 62 ++++++-------- yaserde/tests/ser_option.rs | 147 --------------------------------- yaserde/tests/ser_skip.rs | 22 +---- yaserde/tests/ser_type.rs | 83 ------------------- yaserde/tests/serializer.rs | 61 +++++--------- yaserde/tests/types.rs | 46 +++++++++++ 16 files changed, 574 insertions(+), 823 deletions(-) delete mode 100644 yaserde/tests/de_default.rs delete mode 100644 yaserde/tests/de_option.rs delete mode 100644 yaserde/tests/de_type.rs create mode 100644 yaserde/tests/default.rs create mode 100644 yaserde/tests/flatten.rs create mode 100644 yaserde/tests/option.rs delete mode 100644 yaserde/tests/ser_default.rs delete mode 100644 yaserde/tests/ser_option.rs delete mode 100644 yaserde/tests/ser_type.rs create mode 100644 yaserde/tests/types.rs diff --git a/yaserde/src/lib.rs b/yaserde/src/lib.rs index 8796731..bc27947 100644 --- a/yaserde/src/lib.rs +++ b/yaserde/src/lib.rs @@ -137,3 +137,76 @@ fn default_visitor() { test_type!(visit_u64, "Unexpected u64 \"\""); test_type!(visit_str, "Unexpected str \"\""); } + +#[doc(hidden)] +mod testing { + #[macro_export] + macro_rules! test_for_type { + ($type:ty, $value:expr, $content:expr) => {{ + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(root = "data")] + pub struct Data { + item: $type, + } + + let model = Data { item: $value }; + + let content = if let Some(str_value) = $content { + String::from("") + str_value + "" + } else { + String::from("") + }; + + serialize_and_validate!(model, content); + deserialize_and_validate!(&content, model, Data); + }}; + } + + #[macro_export] + macro_rules! test_for_attribute_type { + ($type: ty, $value: expr, $content: expr) => {{ + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(root = "data")] + pub struct Data { + #[yaserde(attribute)] + item: $type, + } + let model = Data { item: $value }; + + let content = if let Some(str_value) = $content { + "" + } else { + "".to_string() + }; + + serialize_and_validate!(model, content); + deserialize_and_validate!(&content, model, Data); + }}; + } + + #[macro_export] + macro_rules! deserialize_and_validate { + ($content: expr, $model: expr, $struct: tt) => { + let loaded: Result<$struct, String> = yaserde::de::from_str($content); + assert_eq!(loaded, Ok($model)); + }; + } + + #[macro_export] + macro_rules! serialize_and_validate { + ($model: expr, $content: expr) => { + let data: Result = yaserde::ser::to_string(&$model); + + let content = String::from(r#""#) + &$content; + assert_eq!( + data, + Ok( + String::from(content) + .split("\n") + .map(|s| s.trim()) + .collect::() + ) + ); + }; + } +} diff --git a/yaserde/tests/de_default.rs b/yaserde/tests/de_default.rs deleted file mode 100644 index bb0c406..0000000 --- a/yaserde/tests/de_default.rs +++ /dev/null @@ -1,93 +0,0 @@ -#[macro_use] -extern crate yaserde_derive; - -use std::io::Read; -use yaserde::de::from_str; -use yaserde::YaDeserialize; - -macro_rules! convert_and_validate { - ($content: expr, $struct: tt, $model: expr) => { - let loaded: Result<$struct, String> = from_str($content); - assert_eq!(loaded, Ok($model)); - }; -} - -#[test] -fn de_default_field_string() { - fn default_string() -> String { - "my_default_value".to_string() - } - - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "base")] - pub struct XmlStruct { - #[yaserde(default = "default_string")] - background: String, - } - - let content = ""; - convert_and_validate!( - content, - XmlStruct, - XmlStruct { - background: "my_default_value".to_string(), - } - ); -} - -#[test] -fn de_default_field_boolean() { - fn default_boolean() -> bool { - true - } - - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "base")] - pub struct XmlStruct { - #[yaserde(default = "default_boolean")] - background: bool, - } - - let content = ""; - convert_and_validate!(content, XmlStruct, XmlStruct { background: true }); -} - -#[test] -fn de_default_field_number() { - fn default_number() -> u8 { - 6 - } - - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "base")] - pub struct XmlStruct { - #[yaserde(default = "default_number")] - background: u8, - } - - let content = ""; - convert_and_validate!(content, XmlStruct, XmlStruct { background: 6 }); -} - -#[test] -fn de_default_attribute_string() { - fn default_string() -> String { - "my_default_value".to_string() - } - - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "base")] - pub struct XmlStruct { - #[yaserde(attribute, default = "default_string")] - background: String, - } - - let content = ""; - convert_and_validate!( - content, - XmlStruct, - XmlStruct { - background: "my_default_value".to_string(), - } - ); -} diff --git a/yaserde/tests/de_option.rs b/yaserde/tests/de_option.rs deleted file mode 100644 index a986ce4..0000000 --- a/yaserde/tests/de_option.rs +++ /dev/null @@ -1,144 +0,0 @@ -#[macro_use] -extern crate yaserde_derive; - -use std::io::Read; -use yaserde::de::from_str; -use yaserde::YaDeserialize; - -macro_rules! convert_and_validate { - ($type: ty, $value: expr, $content: expr) => {{ - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - item: Option<$type>, - } - - let model = Data { item: $value }; - - let source = if let Some(content) = $content { - String::from("") - + content - + "" - } else { - String::from("") - }; - - let loaded: Result = from_str(&source); - assert_eq!(loaded, Ok(model)); - }}; -} - -macro_rules! convert_and_validate_for_attribute { - ($type: ty, $value: expr, $content: expr) => {{ - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - #[yaserde(attribute)] - item: Option<$type>, - } - - let model = Data { item: $value }; - - let source = if let Some(content) = $content { - String::from("" - } else { - String::from("") - }; - - let loaded: Result = from_str(&source); - assert_eq!(loaded, Ok(model)); - }}; -} - -#[test] -fn de_option() { - convert_and_validate!(String, Some("test".to_string()), Some("test")); - convert_and_validate!(String, None, None); - convert_and_validate!(bool, Some(true), Some("true")); - convert_and_validate!(bool, None, None); - convert_and_validate!(u8, Some(12 as u8), Some("12")); - convert_and_validate!(u8, None, None); - convert_and_validate!(i8, Some(12 as i8), Some("12")); - convert_and_validate!(i8, Some(-12 as i8), Some("-12")); - convert_and_validate!(i8, None, None); - convert_and_validate!(u16, Some(12 as u16), Some("12")); - convert_and_validate!(u16, None, None); - convert_and_validate!(i16, Some(12 as i16), Some("12")); - convert_and_validate!(i16, Some(-12 as i16), Some("-12")); - convert_and_validate!(i16, None, None); - convert_and_validate!(u32, Some(12 as u32), Some("12")); - convert_and_validate!(u32, None, None); - convert_and_validate!(i32, Some(12 as i32), Some("12")); - convert_and_validate!(i32, Some(-12 as i32), Some("-12")); - convert_and_validate!(i32, None, None); - convert_and_validate!(u64, Some(12 as u64), Some("12")); - convert_and_validate!(u64, None, None); - convert_and_validate!(i64, Some(12 as i64), Some("12")); - convert_and_validate!(i64, Some(-12 as i64), Some("-12")); - convert_and_validate!(i64, None, None); - convert_and_validate!(f32, Some(-12.5_f32 as f32), Some("-12.5")); - convert_and_validate!(f32, None, None); - convert_and_validate!(f64, Some(-12.5 as f64), Some("-12.5")); - convert_and_validate!(f64, None, None); - - convert_and_validate_for_attribute!(String, Some("test".to_string()), Some("test")); - convert_and_validate_for_attribute!(String, None, None); - convert_and_validate_for_attribute!(bool, Some(true), Some("true")); - convert_and_validate_for_attribute!(bool, None, None); - convert_and_validate_for_attribute!(u8, Some(12 as u8), Some("12")); - convert_and_validate_for_attribute!(u8, None, None); - convert_and_validate_for_attribute!(i8, Some(12 as i8), Some("12")); - convert_and_validate_for_attribute!(i8, Some(-12 as i8), Some("-12")); - convert_and_validate_for_attribute!(i8, None, None); - convert_and_validate_for_attribute!(u16, Some(12 as u16), Some("12")); - convert_and_validate_for_attribute!(u16, None, None); - convert_and_validate_for_attribute!(i16, Some(12 as i16), Some("12")); - convert_and_validate_for_attribute!(i16, Some(-12 as i16), Some("-12")); - convert_and_validate_for_attribute!(i16, None, None); - convert_and_validate_for_attribute!(u32, Some(12 as u32), Some("12")); - convert_and_validate_for_attribute!(u32, None, None); - convert_and_validate_for_attribute!(i32, Some(12 as i32), Some("12")); - convert_and_validate_for_attribute!(i32, Some(-12 as i32), Some("-12")); - convert_and_validate_for_attribute!(i32, None, None); - convert_and_validate_for_attribute!(u64, Some(12 as u64), Some("12")); - convert_and_validate_for_attribute!(u64, None, None); - convert_and_validate_for_attribute!(i64, Some(12 as i64), Some("12")); - convert_and_validate_for_attribute!(i64, Some(-12 as i64), Some("-12")); - convert_and_validate_for_attribute!(i64, None, None); - convert_and_validate_for_attribute!(f32, Some(-12.5 as f32), Some("-12.5")); - convert_and_validate_for_attribute!(f32, None, None); - convert_and_validate_for_attribute!(f64, Some(-12.5 as f64), Some("-12.5")); - convert_and_validate_for_attribute!(f64, None, None); -} - -#[test] -fn de_option_struct() { - #[derive(YaDeserialize, Debug, PartialEq)] - struct Test { - field: SubTest, - } - - #[derive(YaDeserialize, Debug, PartialEq)] - struct SubTest { - content: Option, - } - - impl Default for SubTest { - fn default() -> Self { - SubTest { content: None } - } - } - - convert_and_validate!( - Test, - Some(Test { - field: SubTest { - content: Some("value".to_string()) - } - }), - Some("value") - ); - convert_and_validate!(Test, None, None); -} diff --git a/yaserde/tests/de_type.rs b/yaserde/tests/de_type.rs deleted file mode 100644 index b8775da..0000000 --- a/yaserde/tests/de_type.rs +++ /dev/null @@ -1,81 +0,0 @@ -#[macro_use] -extern crate yaserde_derive; - -use std::io::Read; -use yaserde::de::from_str; -use yaserde::YaDeserialize; - -macro_rules! convert_and_validate { - ($type:ty, $value:expr, $content:expr) => {{ - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - item: $type, - } - - let model = Data { item: $value }; - - let content = String::from("") - + $content - + ""; - - let loaded: Result = from_str(&content); - assert_eq!(loaded, Ok(model)); - }}; -} - -macro_rules! convert_and_validate_for_attribute { - ($type:ty, $value:expr, $content:expr) => {{ - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - #[yaserde(attribute)] - item: $type, - } - - let model = Data { item: $value }; - - let content = - String::from(""; - - let loaded: Result = from_str(&content); - assert_eq!(loaded, Ok(model)); - }}; -} - -#[test] -fn de_type() { - convert_and_validate!(String, "test".to_string(), "test"); - convert_and_validate!(bool, true, "true"); - convert_and_validate!(u8, 12 as u8, "12"); - convert_and_validate!(i8, 12 as i8, "12"); - convert_and_validate!(i8, -12 as i8, "-12"); - convert_and_validate!(u16, 12 as u16, "12"); - convert_and_validate!(i16, 12 as i16, "12"); - convert_and_validate!(i16, -12 as i16, "-12"); - convert_and_validate!(u32, 12 as u32, "12"); - convert_and_validate!(i32, 12 as i32, "12"); - convert_and_validate!(i32, -12 as i32, "-12"); - convert_and_validate!(u64, 12 as u64, "12"); - convert_and_validate!(i64, 12 as i64, "12"); - convert_and_validate!(i64, -12 as i64, "-12"); - convert_and_validate!(f32, -12.5_f32 as f32, "-12.5"); - convert_and_validate!(f64, -12.5 as f64, "-12.5"); - - convert_and_validate_for_attribute!(String, "test".to_string(), "test"); - convert_and_validate_for_attribute!(bool, true, "true"); - convert_and_validate_for_attribute!(u8, 12 as u8, "12"); - convert_and_validate_for_attribute!(i8, 12 as i8, "12"); - convert_and_validate_for_attribute!(i8, -12 as i8, "-12"); - convert_and_validate_for_attribute!(u16, 12 as u16, "12"); - convert_and_validate_for_attribute!(i16, 12 as i16, "12"); - convert_and_validate_for_attribute!(i16, -12 as i16, "-12"); - convert_and_validate_for_attribute!(u32, 12 as u32, "12"); - convert_and_validate_for_attribute!(i32, 12 as i32, "12"); - convert_and_validate_for_attribute!(i32, -12 as i32, "-12"); - convert_and_validate_for_attribute!(u64, 12 as u64, "12"); - convert_and_validate_for_attribute!(i64, 12 as i64, "12"); - convert_and_validate_for_attribute!(i64, -12 as i64, "-12"); - convert_and_validate_for_attribute!(f32, -12.5 as f32, "-12.5"); - convert_and_validate_for_attribute!(f64, -12.5 as f64, "-12.5"); -} diff --git a/yaserde/tests/default.rs b/yaserde/tests/default.rs new file mode 100644 index 0000000..23be05f --- /dev/null +++ b/yaserde/tests/default.rs @@ -0,0 +1,113 @@ +#[macro_use] +extern crate yaserde; +#[macro_use] +extern crate yaserde_derive; + +use std::io::{Read, Write}; +use yaserde::{YaDeserialize, YaSerialize}; + +#[test] +fn default_field_string() { + fn default_string() -> String { + "my_default_value".to_string() + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(root = "base")] + pub struct XmlStruct { + #[yaserde(default = "default_string")] + background: String, + } + + let model = XmlStruct { + background: "my_default_value".to_string(), + }; + + let content = ""; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); + + + let content = "my_value"; + let model = XmlStruct { + background: "my_value".to_string(), + }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn default_field_boolean() { + fn default_boolean() -> bool { + true + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(root = "base")] + pub struct XmlStruct { + #[yaserde(default = "default_boolean")] + background: bool, + } + + let content = ""; + let model = XmlStruct { background: true }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); + + let content = "false"; + let model = XmlStruct { background: false }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn default_field_number() { + fn default_number() -> u8 { + 6 + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(root = "base")] + pub struct XmlStruct { + #[yaserde(default = "default_number")] + background: u8, + } + + let content = ""; + let model = XmlStruct { background: 6 }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); + + let content = "4"; + let model = XmlStruct { background: 4 }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn de_default_attribute_string() { + fn default_string() -> String { + "my_default_value".to_string() + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(root = "base")] + pub struct XmlStruct { + #[yaserde(attribute, default = "default_string")] + background: String, + } + + let content = ""; + let model = XmlStruct { + background: "my_default_value".to_string(), + }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); + + let content = r#""#; + let model = XmlStruct { + background: "black".to_string(), + }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +} diff --git a/yaserde/tests/flatten.rs b/yaserde/tests/flatten.rs new file mode 100644 index 0000000..33e0293 --- /dev/null +++ b/yaserde/tests/flatten.rs @@ -0,0 +1,145 @@ +#[macro_use] +extern crate yaserde; +#[macro_use] +extern crate yaserde_derive; + +use std::io::{Read, Write}; + +use yaserde::{YaDeserialize, YaSerialize}; + +#[test] +fn basic_flatten() { + #[derive(Default, PartialEq, Debug, YaSerialize)] + struct DateTime { + #[yaserde(flatten)] + date: Date, + time: String, + #[yaserde(flatten)] + kind: DateKind, + } + + #[derive(Default, PartialEq, Debug, YaSerialize)] + struct Date { + year: i32, + month: i32, + day: i32, + #[yaserde(flatten)] + extra: Extra, + #[yaserde(flatten)] + optional_extra: Option, + } + + #[derive(Default, PartialEq, Debug, YaSerialize)] + pub struct Extra { + week: i32, + century: i32, + } + + #[derive(Default, PartialEq, Debug, YaSerialize)] + pub struct OptionalExtra { + lunar_day: i32, + } + + #[derive(PartialEq, Debug, YaSerialize)] + pub enum DateKind { + #[yaserde(rename = "holidays")] + Holidays(Vec), + #[yaserde(rename = "working")] + Working, + } + + impl Default for DateKind { + fn default() -> Self { + DateKind::Working + } + }; + + let model = DateTime { + date: Date { + year: 2020, + month: 1, + day: 1, + extra: Extra { + week: 1, + century: 21, + }, + optional_extra: Some(OptionalExtra { lunar_day: 1 }), + }, + time: "10:40:03".to_string(), + kind: DateKind::Holidays(vec![ + "New Year's Day".into(), + "Novy God Day".into(), + "Polar Bear Swim Day".into(), + ]), + }; + + let content = r#" + + 2020 + 1 + 1 + 1 + 21 + 1 + + New Year's Day + Novy God Day + Polar Bear Swim Day + "#; + + serialize_and_validate!(model, content); +} + +#[test] +fn root_flatten_struct() { + #[derive(YaDeserialize, YaSerialize, PartialEq, Debug)] + #[yaserde(flatten)] + pub struct Content { + binary_data: String, + string_data: String, + } + + let model = Content { + binary_data: "binary".to_string(), + string_data: "string".to_string(), + }; + + let content = "binarystring"; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, Content); +} + +#[test] +fn root_flatten_enum() { + #[derive(YaSerialize, PartialEq, Debug)] + #[yaserde(flatten)] + pub enum Content { + Binary(Binary), + Data(Data), + } + + #[derive(YaSerialize, PartialEq, Debug)] + pub struct Binary { + binary_data: String, + } + + #[derive(YaSerialize, PartialEq, Debug)] + pub struct Data { + string_data: String, + } + + let model = Content::Binary(Binary { + binary_data: "binary".to_string(), + }); + + let content = "binary"; + serialize_and_validate!(model, content); + + let model = Content::Data(Data { + string_data: "string".to_string(), + }); + + let content = "string"; + serialize_and_validate!(model, content); +} diff --git a/yaserde/tests/option.rs b/yaserde/tests/option.rs new file mode 100644 index 0000000..9609796 --- /dev/null +++ b/yaserde/tests/option.rs @@ -0,0 +1,103 @@ +#[macro_use] +extern crate yaserde; +#[macro_use] +extern crate yaserde_derive; + +use std::io::{Read, Write}; +use yaserde::{YaDeserialize, YaSerialize}; + +#[test] +fn basic_option_types() { + test_for_type!(Option::, Some("test".to_string()), Some("test")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(true), Some("true")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as u8), Some("12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as i8), Some("12")); + test_for_type!(Option::, Some(-12 as i8), Some("-12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as u16), Some("12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as i16), Some("12")); + test_for_type!(Option::, Some(-12 as i16), Some("-12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as u32), Some("12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as i32), Some("12")); + test_for_type!(Option::, Some(-12 as i32), Some("-12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as u64), Some("12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(12 as i64), Some("12")); + test_for_type!(Option::, Some(-12 as i64), Some("-12")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(-12.5 as f32), Some("-12.5")); + test_for_type!(Option::, None, None); + test_for_type!(Option::, Some(-12.5 as f64), Some("-12.5")); + test_for_type!(Option::, None, None); + + // test_for_type!(Option::>, None, None); + // test_for_type!(Option::>, Some(vec![0]), Some("0")); + // test_for_type!(Option::>, None, None); + // test_for_type!(Option::>, Some(vec!["test".to_string()]), Some("test")); + + test_for_attribute_type!(Option::, Some("test".to_string()), Some("test")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(true), Some("true")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as u8), Some("12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as i8), Some("12")); + test_for_attribute_type!(Option::, Some(-12 as i8), Some("-12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as u16), Some("12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as i16), Some("12")); + test_for_attribute_type!(Option::, Some(-12 as i16), Some("-12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as u32), Some("12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as i32), Some("12")); + test_for_attribute_type!(Option::, Some(-12 as i32), Some("-12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as u64), Some("12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(12 as i64), Some("12")); + test_for_attribute_type!(Option::, Some(-12 as i64), Some("-12")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(-12.5 as f32), Some("-12.5")); + test_for_attribute_type!(Option::, None, None); + test_for_attribute_type!(Option::, Some(-12.5 as f64), Some("-12.5")); + test_for_attribute_type!(Option::, None, None); +} + +#[test] +fn option_struct() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + struct Test { + field: SubTest, + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + struct SubTest { + content: Option, + } + + impl Default for SubTest { + fn default() -> Self { + SubTest { content: None } + } + } + + test_for_type!( + Option::, + Some(Test { + field: SubTest { + content: Some("value".to_string()) + } + }), + Some("value") + ); + test_for_type!(Option::, None, None); +} diff --git a/yaserde/tests/ser_default.rs b/yaserde/tests/ser_default.rs deleted file mode 100644 index b461a7e..0000000 --- a/yaserde/tests/ser_default.rs +++ /dev/null @@ -1,103 +0,0 @@ -#[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 = to_string(&$model); - assert_eq!(data, Ok(String::from($content))); - }; -} - -#[test] -fn ser_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 = ""; - convert_and_validate!( - XmlStruct { - background: "my_default_value".to_string(), - }, - content - ); - let content = - "my_value"; - convert_and_validate!( - XmlStruct { - background: "my_value".to_string(), - }, - content - ); -} - -#[test] -fn ser_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 = ""; - convert_and_validate!(XmlStruct { background: true }, content); - - let content = - "false"; - convert_and_validate!(XmlStruct { background: false }, content); -} - -#[test] -fn ser_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 = ""; - convert_and_validate!(XmlStruct { background: 6 }, content); -} - -#[test] -fn ser_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 = ""; - convert_and_validate!( - XmlStruct { - background: "my_default_value".to_string(), - }, - content - ); -} diff --git a/yaserde/tests/ser_enum.rs b/yaserde/tests/ser_enum.rs index c5c38e3..4de471d 100644 --- a/yaserde/tests/ser_enum.rs +++ b/yaserde/tests/ser_enum.rs @@ -1,25 +1,11 @@ #[macro_use] +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 = to_string(&$model); - assert_eq!( - data, - Ok( - String::from($content) - .split("\n") - .map(|s| s.trim()) - .collect::() - ) - ); - }; -} - #[test] fn ser_enum() { #[derive(YaSerialize, PartialEq, Debug)] @@ -77,8 +63,8 @@ fn ser_enum() { color: Color::Black, }; - let content = r#"Black"#; - convert_and_validate!(model, content); + let content = "Black"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Color::Custom { @@ -103,7 +89,7 @@ fn ser_enum() { }, }; - let content = r#" + let content = r#" true 8 @@ -123,7 +109,7 @@ fn ser_enum() { "#; - convert_and_validate!(model, content); + serialize_and_validate!(model, content); } #[test] @@ -144,8 +130,8 @@ fn ser_attribute_enum() { let model = XmlStruct { color: Color::Pink }; - let content = r#""#; - convert_and_validate!(model, content); + let content = r#""#; + serialize_and_validate!(model, content); } #[test] @@ -190,73 +176,72 @@ fn ser_unnamed_enum() { color: Enum::Field(String::from("some_text")), }; - let content = - r#"some_text"#; - convert_and_validate!(model, content); + let content = "some_text"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::FullPath(String::from("some_text")), }; - let content = r#"some_text"#; - convert_and_validate!(model, content); + let content = "some_text"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::Integer(56), }; - let content = - r#"56"#; - convert_and_validate!(model, content); + let content = "56"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::UserStruct(OtherStruct { fi: 24, se: 42 }), }; - let content = r#"2442"#; - convert_and_validate!(model, content); + let content = "2442"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::OptionString(Some(String::from("some_text"))), }; - let content = r#"some_text"#; - convert_and_validate!(model, content); + let content = "some_text"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::OptionString(None), }; - let content = r#""#; - convert_and_validate!(model, content); + let content = ""; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::OptionUserStruct(Some(OtherStruct { fi: 12, se: 23 })), }; - let content = r#"1223"#; - convert_and_validate!(model, content); + let content = + "1223"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::OptionUserStruct(None), }; - let content = r#""#; - convert_and_validate!(model, content); + let content = ""; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::Strings(vec![String::from("abc"), String::from("def")]), }; - let content = r#"abcdef"#; - convert_and_validate!(model, content); + let content = "abcdef"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::Ints(vec![23, 45]), }; - let content = r#"2345"#; - convert_and_validate!(model, content); + let content = "2345"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::Structs(vec![ @@ -265,21 +250,20 @@ fn ser_unnamed_enum() { ]), }; - let content = r#"12233445"#; - convert_and_validate!(model, content); + let content = "12233445"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::ToRename(87), }; - let content = - r#"87"#; - convert_and_validate!(model, content); + let content = "87"; + serialize_and_validate!(model, content); let model = XmlStruct { color: Enum::ToRenameDots(84), }; - let content = r#"84"#; - convert_and_validate!(model, content); + let content = "84"; + serialize_and_validate!(model, content); } diff --git a/yaserde/tests/ser_flatten.rs b/yaserde/tests/ser_flatten.rs index 0127ed1..b4c04ec 100644 --- a/yaserde/tests/ser_flatten.rs +++ b/yaserde/tests/ser_flatten.rs @@ -1,25 +1,11 @@ #[macro_use] +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 = to_string(&$model); - assert_eq!( - data, - Ok( - String::from($content) - .split("\n") - .map(|s| s.trim()) - .collect::() - ) - ); - }; -} - #[test] fn ser_flatten() { #[derive(Default, PartialEq, Debug, YaSerialize)] @@ -87,7 +73,6 @@ fn ser_flatten() { }; let content = r#" - 2020 1 @@ -101,7 +86,7 @@ fn ser_flatten() { Polar Bear Swim Day "#; - convert_and_validate!(model, content); + serialize_and_validate!(model, content); } #[test] @@ -117,8 +102,8 @@ fn ser_root_flatten_struct() { binary_data: "binary".to_string(), string_data: "string".to_string(), }; - let content = r#"binarystring"#; - convert_and_validate!(model, content); + let content = "binarystring"; + serialize_and_validate!(model, content); } #[test] @@ -143,14 +128,12 @@ fn ser_root_flatten_enum() { let model = Content::Binary(Binary { binary_data: "binary".to_string(), }); - let content = - r#"binary"#; - convert_and_validate!(model, content); + let content = "binary"; + serialize_and_validate!(model, content); let model = Content::Data(Data { string_data: "string".to_string(), }); - let content = - r#"string"#; - convert_and_validate!(model, content); + let content = "string"; + serialize_and_validate!(model, content); } diff --git a/yaserde/tests/ser_namespace.rs b/yaserde/tests/ser_namespace.rs index 5af32e8..906735b 100644 --- a/yaserde/tests/ser_namespace.rs +++ b/yaserde/tests/ser_namespace.rs @@ -1,25 +1,11 @@ #[macro_use] +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 = to_string(&$model); - assert_eq!( - data, - Ok( - String::from($content) - .split("\n") - .map(|s| s.trim()) - .collect::() - ) - ); - }; -} - #[test] fn ser_struct_namespace() { #[derive(YaSerialize, PartialEq, Debug)] @@ -37,8 +23,9 @@ fn ser_struct_namespace() { item: "something".to_string(), }; - let content = "something"; - convert_and_validate!(model, content); + let content = + r#"something"#; + serialize_and_validate!(model, content); } #[test] @@ -58,13 +45,13 @@ fn ser_enum_namespace() { let model = XmlStruct::Item; - let content = "ns:Item"; - convert_and_validate!(model, content); + let content = r#"ns:Item"#; + serialize_and_validate!(model, content); let model = XmlStruct::ItemWithField("Value".to_string()); - let content = "Value"; - convert_and_validate!(model, content); + let content = r#"Value"#; + serialize_and_validate!(model, content); } #[test] @@ -87,8 +74,8 @@ fn ser_struct_multi_namespace() { item_2: "something 2".to_string(), }; - let content = "something 1something 2"; - convert_and_validate!(model, content); + let content = r#"something 1something 2"#; + serialize_and_validate!(model, content); } #[test] @@ -107,11 +94,11 @@ fn ser_enum_multi_namespace() { } let model1 = XmlStruct::Item1; - let content = "ns1:Item1"; - convert_and_validate!(model1, content); + let content = r#"ns1:Item1"#; + serialize_and_validate!(model1, content); let model2 = XmlStruct::Item2; - let content = "ns2:Item2"; - convert_and_validate!(model2, content); + let content = r#"ns2:Item2"#; + serialize_and_validate!(model2, content); } #[test] @@ -134,8 +121,8 @@ fn ser_struct_attribute_namespace() { item_2: "something 2".to_string(), }; - let content = "something 1"; - convert_and_validate!(model, content); + let content = r#"something 1"#; + serialize_and_validate!(model, content); } #[test] @@ -154,8 +141,8 @@ fn ser_struct_default_namespace() { item: "something".to_string(), }; - let content = "something"; - convert_and_validate!(model, content); + let content = r#"something"#; + serialize_and_validate!(model, content); } #[test] @@ -175,8 +162,8 @@ fn ser_struct_default_namespace_via_attribute() { item: "something".to_string(), }; - let content = "something"; - convert_and_validate!(model, content); + let content = r#"something"#; + serialize_and_validate!(model, content); } #[test] @@ -198,8 +185,8 @@ fn ser_struct_default_namespace_via_attribute_with_prefix() { item: "something".to_string(), }; - let content = "something"; - convert_and_validate!(model, content); + let content = r#"something"#; + serialize_and_validate!(model, content); } #[test] @@ -219,12 +206,11 @@ fn ser_struct_namespace_nested() { nested: A, } - convert_and_validate!( + serialize_and_validate!( B { nested: A { alpha: 32 } }, r#" - 32 diff --git a/yaserde/tests/ser_option.rs b/yaserde/tests/ser_option.rs deleted file mode 100644 index 26f1c08..0000000 --- a/yaserde/tests/ser_option.rs +++ /dev/null @@ -1,147 +0,0 @@ -#[macro_use] -extern crate yaserde_derive; - -use std::io::Write; -use yaserde::ser::to_string; -use yaserde::YaSerialize; - -macro_rules! convert_and_validate { - ($type: ty, $value: expr, $content: expr) => {{ - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - item: Option<$type>, - } - let model = Data { item: $value }; - - let data: Result = to_string(&model); - - let content = if let Some(str_value) = $content { - "".to_string() + str_value + "" - } else { - "".to_string() - }; - - let content = String::from("") + &content; - assert_eq!(data, Ok(content)); - }}; -} - -macro_rules! convert_and_validate_as_attribute { - ($type: ty, $value: expr, $content: expr) => {{ - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - #[yaserde(attribute)] - item: Option<$type>, - } - let model = Data { item: $value }; - - let data: Result = to_string(&model); - - let content = if let Some(str_value) = $content { - "" - } else { - "".to_string() - }; - - let content = String::from("") + &content; - assert_eq!(data, Ok(content)); - }}; -} - -#[test] -fn ser_option() { - convert_and_validate!(String, Some("test".to_string()), Some("test")); - convert_and_validate!(String, None, None); - convert_and_validate!(bool, Some(true), Some("true")); - convert_and_validate!(bool, None, None); - convert_and_validate!(u8, Some(12 as u8), Some("12")); - convert_and_validate!(u8, None, None); - convert_and_validate!(i8, Some(12 as i8), Some("12")); - convert_and_validate!(i8, Some(-12 as i8), Some("-12")); - convert_and_validate!(i8, None, None); - convert_and_validate!(u16, Some(12 as u16), Some("12")); - convert_and_validate!(u16, None, None); - convert_and_validate!(i16, Some(12 as i16), Some("12")); - convert_and_validate!(i16, Some(-12 as i16), Some("-12")); - convert_and_validate!(i16, None, None); - convert_and_validate!(u32, Some(12 as u32), Some("12")); - convert_and_validate!(u32, None, None); - convert_and_validate!(i32, Some(12 as i32), Some("12")); - convert_and_validate!(i32, Some(-12 as i32), Some("-12")); - convert_and_validate!(i32, None, None); - convert_and_validate!(u64, Some(12 as u64), Some("12")); - convert_and_validate!(u64, None, None); - convert_and_validate!(i64, Some(12 as i64), Some("12")); - convert_and_validate!(i64, Some(-12 as i64), Some("-12")); - convert_and_validate!(i64, None, None); - convert_and_validate!(f32, Some(-12.5 as f32), Some("-12.5")); - convert_and_validate!(f32, None, None); - convert_and_validate!(f64, Some(-12.5 as f64), Some("-12.5")); - convert_and_validate!(f64, None, None); - - convert_and_validate!(Vec, None, None); - convert_and_validate!(Vec, Some(vec![0]), Some("0")); - convert_and_validate!(Vec, None, None); - convert_and_validate!(Vec, Some(vec!["test".to_string()]), Some("test")); - - convert_and_validate_as_attribute!(String, Some("test".to_string()), Some("test")); - convert_and_validate_as_attribute!(String, None, None); - convert_and_validate_as_attribute!(bool, Some(true), Some("true")); - convert_and_validate_as_attribute!(bool, None, None); - convert_and_validate_as_attribute!(u8, Some(12 as u8), Some("12")); - convert_and_validate_as_attribute!(u8, None, None); - convert_and_validate_as_attribute!(i8, Some(12 as i8), Some("12")); - convert_and_validate_as_attribute!(i8, Some(-12 as i8), Some("-12")); - convert_and_validate_as_attribute!(i8, None, None); - convert_and_validate_as_attribute!(u16, Some(12 as u16), Some("12")); - convert_and_validate_as_attribute!(u16, None, None); - convert_and_validate_as_attribute!(i16, Some(12 as i16), Some("12")); - convert_and_validate_as_attribute!(i16, Some(-12 as i16), Some("-12")); - convert_and_validate_as_attribute!(i16, None, None); - convert_and_validate_as_attribute!(u32, Some(12 as u32), Some("12")); - convert_and_validate_as_attribute!(u32, None, None); - convert_and_validate_as_attribute!(i32, Some(12 as i32), Some("12")); - convert_and_validate_as_attribute!(i32, Some(-12 as i32), Some("-12")); - convert_and_validate_as_attribute!(i32, None, None); - convert_and_validate_as_attribute!(u64, Some(12 as u64), Some("12")); - convert_and_validate_as_attribute!(u64, None, None); - convert_and_validate_as_attribute!(i64, Some(12 as i64), Some("12")); - convert_and_validate_as_attribute!(i64, Some(-12 as i64), Some("-12")); - convert_and_validate_as_attribute!(i64, None, None); - convert_and_validate_as_attribute!(f32, Some(-12.5 as f32), Some("-12.5")); - convert_and_validate_as_attribute!(f32, None, None); - convert_and_validate_as_attribute!(f64, Some(-12.5 as f64), Some("-12.5")); - convert_and_validate_as_attribute!(f64, None, None); -} - -#[test] -fn de_option_struct() { - #[derive(YaSerialize, Debug, PartialEq)] - struct Test { - field: SubTest, - } - - #[derive(YaSerialize, Debug, PartialEq)] - struct SubTest { - content: Option, - } - - impl Default for SubTest { - fn default() -> Self { - SubTest { content: None } - } - } - - convert_and_validate!( - Test, - Some(Test { - field: SubTest { - content: Some("value".to_string()) - } - }), - Some("value") - ); - convert_and_validate!(Test, None, None); -} diff --git a/yaserde/tests/ser_skip.rs b/yaserde/tests/ser_skip.rs index 53c6be0..05cb74b 100644 --- a/yaserde/tests/ser_skip.rs +++ b/yaserde/tests/ser_skip.rs @@ -1,25 +1,11 @@ #[macro_use] +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 = to_string(&$model); - assert_eq!( - data, - Ok( - String::from($content) - .split("\n") - .map(|s| s.trim()) - .collect::() - ) - ); - }; -} - #[test] fn ser_skip_serializing_if_for_struct() { #[derive(YaSerialize, PartialEq, Debug)] @@ -60,6 +46,6 @@ fn ser_skip_serializing_if_for_struct() { option_string_item: Some("something".to_string()), }; - let content = ""; - convert_and_validate!(model, content); + let content = ""; + serialize_and_validate!(model, content); } diff --git a/yaserde/tests/ser_type.rs b/yaserde/tests/ser_type.rs deleted file mode 100644 index 1506cc2..0000000 --- a/yaserde/tests/ser_type.rs +++ /dev/null @@ -1,83 +0,0 @@ -#[macro_use] -extern crate yaserde_derive; - -use std::io::Write; -use yaserde::ser::to_string; -use yaserde::YaSerialize; - -macro_rules! convert_and_validate { - ($type: ty, $value: expr, $content: expr) => {{ - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - item: $type, - } - let model = Data { item: $value }; - - let data: Result = to_string(&model); - let content = if $content == "" { - String::from("") - } else { - String::from("") - + $content - + "" - }; - assert_eq!(data, Ok(content)); - }}; -} - -macro_rules! convert_and_validate_as_attribute { - ($type: ty, $value: expr, $content: expr) => {{ - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "data")] - pub struct Data { - #[yaserde(attribute)] - item: $type, - } - let model = Data { item: $value }; - - let data: Result = to_string(&model); - let content = - String::from(""; - assert_eq!(data, Ok(content)); - }}; -} - -#[test] -fn ser_type() { - convert_and_validate!(String, "test".to_string(), "test"); - convert_and_validate!(bool, true, "true"); - convert_and_validate!(u8, 12 as u8, "12"); - convert_and_validate!(i8, 12 as i8, "12"); - convert_and_validate!(i8, -12 as i8, "-12"); - convert_and_validate!(u16, 12 as u16, "12"); - convert_and_validate!(i16, 12 as i16, "12"); - convert_and_validate!(i16, -12 as i16, "-12"); - convert_and_validate!(u32, 12 as u32, "12"); - convert_and_validate!(i32, 12 as i32, "12"); - convert_and_validate!(i32, -12 as i32, "-12"); - convert_and_validate!(u64, 12 as u64, "12"); - convert_and_validate!(i64, 12 as i64, "12"); - convert_and_validate!(i64, -12 as i64, "-12"); - convert_and_validate!(f32, -12.5 as f32, "-12.5"); - convert_and_validate!(f64, -12.5 as f64, "-12.5"); - convert_and_validate!(Vec, vec![], ""); - convert_and_validate!(Vec, vec!["test".to_string()], "test"); - - convert_and_validate_as_attribute!(String, "test".to_string(), "test"); - convert_and_validate_as_attribute!(bool, true, "true"); - convert_and_validate_as_attribute!(u8, 12 as u8, "12"); - convert_and_validate_as_attribute!(i8, 12 as i8, "12"); - convert_and_validate_as_attribute!(i8, -12 as i8, "-12"); - convert_and_validate_as_attribute!(u16, 12 as u16, "12"); - convert_and_validate_as_attribute!(i16, 12 as i16, "12"); - convert_and_validate_as_attribute!(i16, -12 as i16, "-12"); - convert_and_validate_as_attribute!(u32, 12 as u32, "12"); - convert_and_validate_as_attribute!(i32, 12 as i32, "12"); - convert_and_validate_as_attribute!(i32, -12 as i32, "-12"); - convert_and_validate_as_attribute!(u64, 12 as u64, "12"); - convert_and_validate_as_attribute!(i64, 12 as i64, "12"); - convert_and_validate_as_attribute!(i64, -12 as i64, "-12"); - convert_and_validate_as_attribute!(f32, -12.5 as f32, "-12.5"); - convert_and_validate_as_attribute!(f64, -12.5 as f64, "-12.5"); -} diff --git a/yaserde/tests/serializer.rs b/yaserde/tests/serializer.rs index c3ff11b..2814f81 100644 --- a/yaserde/tests/serializer.rs +++ b/yaserde/tests/serializer.rs @@ -1,25 +1,11 @@ #[macro_use] +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 = to_string(&$model); - assert_eq!( - data, - Ok( - String::from($content) - .split("\n") - .map(|s| s.trim()) - .collect::() - ) - ); - }; -} - #[test] fn ser_basic() { #[derive(YaSerialize, PartialEq, Debug)] @@ -32,8 +18,8 @@ fn ser_basic() { item: "something".to_string(), }; - let content = "something"; - convert_and_validate!(model, content); + let content = "something"; + serialize_and_validate!(model, content); } #[test] @@ -48,8 +34,8 @@ fn ser_list_of_items() { items: vec!["something1".to_string(), "something2".to_string()], }; - let content = "something1something2"; - convert_and_validate!(model, content); + let content = "something1something2"; + serialize_and_validate!(model, content); #[derive(YaSerialize, PartialEq, Debug)] #[yaserde(root = "base")] @@ -74,8 +60,9 @@ fn ser_list_of_items() { ], }; - let content = "something1something2"; - convert_and_validate!(model2, content); + let content = + "something1something2"; + serialize_and_validate!(model2, content); } #[test] @@ -117,8 +104,8 @@ fn ser_attributes() { }, }; - let content = ""; - convert_and_validate!(model, content); + let content = r#""#; + serialize_and_validate!(model, content); } #[test] @@ -158,24 +145,20 @@ fn ser_attributes_complex() { } } - convert_and_validate!( + serialize_and_validate!( Struct { attr_option_string: None, attr_option_enum: None, }, - r#" - - - "# + "" ); - convert_and_validate!( + serialize_and_validate!( Struct { attr_option_string: Some("some value".to_string()), attr_option_enum: Some(other_mod::AttrEnum::Variant2), }, r#" - "# ); @@ -224,8 +207,8 @@ fn ser_rename() { version: "2.0.2".into(), }; - let content = "2.0.2"; - convert_and_validate!(model, content); + let content = r#"2.0.2"#; + serialize_and_validate!(model, content); } #[test] @@ -273,8 +256,8 @@ fn ser_text_content_with_attributes() { }, }; - let content = "text_content"; - convert_and_validate!(model, content); + let content = r#"text_content"#; + serialize_and_validate!(model, content); } #[test] @@ -289,8 +272,8 @@ fn ser_name_issue_21() { name: "something".to_string(), }; - let content = "something"; - convert_and_validate!(model, content); + let content = "something"; + serialize_and_validate!(model, content); } #[test] @@ -326,6 +309,6 @@ fn ser_custom() { month: 1, day: Day { value: 5 }, }; - let content = "2020110"; - convert_and_validate!(model, content); + let content = "2020110"; + serialize_and_validate!(model, content); } diff --git a/yaserde/tests/types.rs b/yaserde/tests/types.rs new file mode 100644 index 0000000..de5e2d4 --- /dev/null +++ b/yaserde/tests/types.rs @@ -0,0 +1,46 @@ +#[macro_use] +extern crate yaserde; +#[macro_use] +extern crate yaserde_derive; + +use std::io::{Read, Write}; +use yaserde::{YaDeserialize, YaSerialize}; + +#[test] +fn ser_type() { + test_for_type!(String, "test".to_string(), Some("test")); + test_for_type!(bool, true, Some("true")); + test_for_type!(u8, 12 as u8, Some("12")); + test_for_type!(i8, 12 as i8, Some("12")); + test_for_type!(i8, -12 as i8, Some("-12")); + test_for_type!(u16, 12 as u16, Some("12")); + test_for_type!(i16, 12 as i16, Some("12")); + test_for_type!(i16, -12 as i16, Some("-12")); + test_for_type!(u32, 12 as u32, Some("12")); + test_for_type!(i32, 12 as i32, Some("12")); + test_for_type!(i32, -12 as i32, Some("-12")); + test_for_type!(u64, 12 as u64, Some("12")); + test_for_type!(i64, 12 as i64, Some("12")); + test_for_type!(i64, -12 as i64, Some("-12")); + test_for_type!(f32, -12.5 as f32, Some("-12.5")); + test_for_type!(f64, -12.5 as f64, Some("-12.5")); + test_for_type!(Vec::, vec![], None); + test_for_type!(Vec::, vec!["test".to_string()], Some("test")); + + test_for_attribute_type!(String, "test".to_string(), Some("test")); + test_for_attribute_type!(bool, true, Some("true")); + test_for_attribute_type!(u8, 12 as u8, Some("12")); + test_for_attribute_type!(i8, 12 as i8, Some("12")); + test_for_attribute_type!(i8, -12 as i8, Some("-12")); + test_for_attribute_type!(u16, 12 as u16, Some("12")); + test_for_attribute_type!(i16, 12 as i16, Some("12")); + test_for_attribute_type!(i16, -12 as i16, Some("-12")); + test_for_attribute_type!(u32, 12 as u32, Some("12")); + test_for_attribute_type!(i32, 12 as i32, Some("12")); + test_for_attribute_type!(i32, -12 as i32, Some("-12")); + test_for_attribute_type!(u64, 12 as u64, Some("12")); + test_for_attribute_type!(i64, 12 as i64, Some("12")); + test_for_attribute_type!(i64, -12 as i64, Some("-12")); + test_for_attribute_type!(f32, -12.5 as f32, Some("-12.5")); + test_for_attribute_type!(f64, -12.5 as f64, Some("-12.5")); +} From ccf353ce6b0572cb8a953200c21ddc81c8ee88c1 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Tue, 21 Apr 2020 11:16:03 +0200 Subject: [PATCH 2/7] restructure unit tests to check serialization and deserialisation on same features --- yaserde/tests/de_flatten.rs | 166 -------- yaserde/tests/de_namespace.rs | 144 ------- yaserde/tests/default.rs | 7 +- yaserde/tests/{ser_enum.rs => enum.rs} | 59 ++- yaserde/tests/flatten.rs | 11 +- yaserde/tests/namespace.rs | 442 ++++++++++++++++++++++ yaserde/tests/ser_flatten.rs | 139 ------- yaserde/tests/ser_namespace.rs | 221 ----------- yaserde/tests/{ser_skip.rs => skip_if.rs} | 2 +- 9 files changed, 497 insertions(+), 694 deletions(-) delete mode 100644 yaserde/tests/de_flatten.rs delete mode 100644 yaserde/tests/de_namespace.rs rename yaserde/tests/{ser_enum.rs => enum.rs} (76%) create mode 100644 yaserde/tests/namespace.rs delete mode 100644 yaserde/tests/ser_flatten.rs delete mode 100644 yaserde/tests/ser_namespace.rs rename yaserde/tests/{ser_skip.rs => skip_if.rs} (96%) diff --git a/yaserde/tests/de_flatten.rs b/yaserde/tests/de_flatten.rs deleted file mode 100644 index d385430..0000000 --- a/yaserde/tests/de_flatten.rs +++ /dev/null @@ -1,166 +0,0 @@ -#[macro_use] -extern crate yaserde_derive; - -use std::io::Read; -use yaserde::de::from_str; -use yaserde::YaDeserialize; - -macro_rules! convert_and_validate { - ($content: expr, $struct: tt, $model: expr) => { - let loaded: Result<$struct, String> = from_str($content); - assert_eq!(loaded, Ok($model)); - }; -} - -#[test] -fn de_root_flatten_struct() { - #[derive(Default, PartialEq, Debug, YaDeserialize)] - #[yaserde(flatten)] - struct Content { - binary_data: String, - string_data: String, - } - - let content = r#" - - binary - string - "#; - - convert_and_validate!( - content, - Content, - Content { - binary_data: "binary".to_string(), - string_data: "string".to_string(), - } - ); -} - -#[test] -fn de_root_flatten_enum() { - #[derive(PartialEq, Debug, YaDeserialize)] - #[yaserde(flatten)] - pub enum Content { - Binary(Binary), - Data(Data), - Unknown, - } - - impl Default for Content { - fn default() -> Self { - Content::Unknown - } - } - - #[derive(Default, PartialEq, Debug, YaDeserialize)] - pub struct Binary { - binary_data: String, - } - - #[derive(Default, PartialEq, Debug, YaDeserialize)] - pub struct Data { - string_data: String, - } - - let content = r#" - - - binary - - "#; - - convert_and_validate!( - content, - Content, - Content::Binary(Binary { - binary_data: "binary".to_string(), - }) - ); -} - -#[test] -fn de_flatten() { - #[derive(Default, PartialEq, Debug, YaDeserialize)] - struct DateTime { - #[yaserde(flatten)] - date: Date, - time: String, - #[yaserde(flatten)] - kind: DateKind, - } - - #[derive(Default, PartialEq, Debug, YaDeserialize)] - struct Date { - year: i32, - month: i32, - day: i32, - #[yaserde(flatten)] - extra: Extra, - #[yaserde(flatten)] - optional_extra: Option, - } - - #[derive(Default, PartialEq, Debug, YaDeserialize)] - pub struct Extra { - week: i32, - century: i32, - } - - #[derive(Default, PartialEq, Debug, YaDeserialize)] - pub struct OptionalExtra { - lunar_day: i32, - } - - #[derive(PartialEq, Debug, YaDeserialize)] - pub enum DateKind { - #[yaserde(rename = "holidays")] - Holidays(Vec), - #[yaserde(rename = "working")] - Working, - } - - impl Default for DateKind { - fn default() -> Self { - DateKind::Working - } - }; - - let content = r#" - - - 2020 - 1 - 1 - 1 - 21 - 1 - - New Year's Day - Novy God Day - Polar Bear Swim Day - - "#; - convert_and_validate!( - content, - DateTime, - DateTime { - date: Date { - year: 2020, - month: 1, - day: 1, - extra: Extra { - week: 1, - century: 21, - }, - optional_extra: Some(OptionalExtra { lunar_day: 1 }), - }, - time: "10:40:03".to_string(), - kind: DateKind::Holidays(vec![ - "New Year's Day".into(), - "Novy God Day".into(), - "Polar Bear Swim Day".into() - ]) - } - ); -} diff --git a/yaserde/tests/de_namespace.rs b/yaserde/tests/de_namespace.rs deleted file mode 100644 index dd3d94c..0000000 --- a/yaserde/tests/de_namespace.rs +++ /dev/null @@ -1,144 +0,0 @@ -#[macro_use] -extern crate yaserde_derive; - -use std::io::Read; -use yaserde::de::from_str; -use yaserde::YaDeserialize; - -macro_rules! convert_and_validate { - ($content: expr, $struct: tt, $model: expr) => { - let loaded: Result<$struct, String> = from_str($content); - assert_eq!(loaded, Ok($model)); - }; -} - -#[test] -fn de_struct_namespace() { - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde( - root = "book", - prefix = "ns", - namespace = "ns: http://www.sample.com/ns/domain", - namespace = "ns2: http://www.sample.com/ns/domain_2" - )] - pub struct Book { - #[yaserde(prefix = "ns")] - author: String, - #[yaserde(prefix = "ns2")] - title: String, - } - - let content = r#" - - Antoine de Saint-Exupéry - Little prince - - "#; - convert_and_validate!( - content, - Book, - Book { - author: String::from("Antoine de Saint-Exupéry"), - title: String::from("Little prince"), - } - ); - - let content = r#" - - Antoine de Saint-Exupéry - Little prince - - "#; - convert_and_validate!( - content, - Book, - Book { - author: String::from("Antoine de Saint-Exupéry"), - title: String::from("Little prince"), - } - ); - - let content = r#" - - Antoine de Saint-Exupéry - Little prince - - "#; - convert_and_validate!( - content, - Book, - Book { - author: String::from("Antoine de Saint-Exupéry"), - title: String::from("Little prince"), - } - ); - - let content = r#" - - Antoine de Saint-Exupéry - Little prince - "#; - let loaded: Result = from_str(content); - assert_eq!( - loaded, - Err("bad namespace for book, found http://www.sample.com/ns/domain2".to_string()) - ); -} - -#[test] -fn de_struct_namespace_nested() { - #[derive(YaDeserialize, Default, PartialEq, Debug)] - #[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")] - struct A { - #[yaserde(prefix = "nsa")] - alpha: i32, - } - - #[derive(YaDeserialize, Default, PartialEq, Debug)] - #[yaserde(prefix = "nsb", namespace = "nsb: http://www.sample.com/ns/b")] - struct B { - // Note that name `nested` resides in `nsb` though it has a type from `nsa` - #[yaserde(prefix = "nsb")] - nested: A, - } - - convert_and_validate!( - r#" - - - - 32 - - - "#, - B, - B { - nested: A { alpha: 32 } - } - ); -} - -#[test] -fn de_enum_namespace() { - #[derive(YaDeserialize, PartialEq, Debug)] - #[yaserde( - root = "root", - prefix = "ns", - namespace = "ns: http://www.sample.com/ns/domain" - )] - pub enum XmlStruct { - #[yaserde(prefix = "ns")] - Item, - } - - impl Default for XmlStruct { - fn default() -> XmlStruct { - XmlStruct::Item - } - } - - let content = "ns:Item"; - convert_and_validate!(content, XmlStruct, XmlStruct::Item); -} diff --git a/yaserde/tests/default.rs b/yaserde/tests/default.rs index 23be05f..38fb151 100644 --- a/yaserde/tests/default.rs +++ b/yaserde/tests/default.rs @@ -27,11 +27,10 @@ fn default_field_string() { serialize_and_validate!(model, content); deserialize_and_validate!(content, model, XmlStruct); - let content = "my_value"; let model = XmlStruct { - background: "my_value".to_string(), - }; + background: "my_value".to_string(), + }; serialize_and_validate!(model, content); deserialize_and_validate!(content, model, XmlStruct); } @@ -85,7 +84,7 @@ fn default_field_number() { } #[test] -fn de_default_attribute_string() { +fn default_attribute_string() { fn default_string() -> String { "my_default_value".to_string() } diff --git a/yaserde/tests/ser_enum.rs b/yaserde/tests/enum.rs similarity index 76% rename from yaserde/tests/ser_enum.rs rename to yaserde/tests/enum.rs index 4de471d..ab96c42 100644 --- a/yaserde/tests/ser_enum.rs +++ b/yaserde/tests/enum.rs @@ -3,18 +3,18 @@ extern crate yaserde; #[macro_use] extern crate yaserde_derive; -use std::io::Write; -use yaserde::YaSerialize; +use std::io::{Read, Write}; +use yaserde::{YaDeserialize, YaSerialize}; #[test] -fn ser_enum() { - #[derive(YaSerialize, PartialEq, Debug)] +fn basic_enum() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde(root = "base")] pub struct XmlStruct { color: Color, } - #[derive(YaSerialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde(root = "color")] pub enum Color { White, @@ -46,25 +46,32 @@ fn ser_enum() { assert_eq!(Color::default(), Color::White); - #[derive(YaSerialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] pub struct RGBColor { red: String, green: String, blue: String, } - #[derive(YaSerialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] pub enum Alpha { Transparent, Opaque, } + impl Default for Alpha { + fn default() -> Alpha { + Alpha::Transparent + } + } + let model = XmlStruct { color: Color::Black, }; let content = "Black"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Color::Custom { @@ -110,45 +117,54 @@ fn ser_enum() { "#; serialize_and_validate!(model, content); + // TODO + // deserialize_and_validate!(content, model, XmlStruct); } #[test] -fn ser_attribute_enum() { - #[derive(YaSerialize, PartialEq, Debug)] +fn attribute_enum() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde(root = "base")] pub struct XmlStruct { #[yaserde(attribute)] color: Color, } - #[derive(YaSerialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde(root = "color")] pub enum Color { #[yaserde(rename = "pink")] Pink, } + impl Default for Color { + fn default() -> Color { + Color::Pink + } + } + let model = XmlStruct { color: Color::Pink }; let content = r#""#; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); } #[test] -fn ser_unnamed_enum() { - #[derive(YaSerialize, PartialEq, Debug)] +fn unnamed_enum() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde(root = "base")] pub struct XmlStruct { color: Enum, } - #[derive(YaSerialize, PartialEq, Debug, Default)] + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] pub struct OtherStruct { fi: i32, se: i32, } - #[derive(YaSerialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] pub enum Enum { Simple, Field(String), @@ -178,6 +194,7 @@ fn ser_unnamed_enum() { let content = "some_text"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::FullPath(String::from("some_text")), @@ -185,6 +202,7 @@ fn ser_unnamed_enum() { let content = "some_text"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::Integer(56), @@ -192,6 +210,7 @@ fn ser_unnamed_enum() { let content = "56"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::UserStruct(OtherStruct { fi: 24, se: 42 }), @@ -199,6 +218,7 @@ fn ser_unnamed_enum() { let content = "2442"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::OptionString(Some(String::from("some_text"))), @@ -206,6 +226,7 @@ fn ser_unnamed_enum() { let content = "some_text"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::OptionString(None), @@ -213,6 +234,8 @@ fn ser_unnamed_enum() { let content = ""; serialize_and_validate!(model, content); + // TODO + // deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::OptionUserStruct(Some(OtherStruct { fi: 12, se: 23 })), @@ -221,6 +244,7 @@ fn ser_unnamed_enum() { let content = "1223"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::OptionUserStruct(None), @@ -228,6 +252,8 @@ fn ser_unnamed_enum() { let content = ""; serialize_and_validate!(model, content); + // TODO + // deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::Strings(vec![String::from("abc"), String::from("def")]), @@ -235,6 +261,7 @@ fn ser_unnamed_enum() { let content = "abcdef"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::Ints(vec![23, 45]), @@ -242,6 +269,7 @@ fn ser_unnamed_enum() { let content = "2345"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::Structs(vec![ @@ -252,6 +280,7 @@ fn ser_unnamed_enum() { let content = "12233445"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::ToRename(87), @@ -259,6 +288,7 @@ fn ser_unnamed_enum() { let content = "87"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); let model = XmlStruct { color: Enum::ToRenameDots(84), @@ -266,4 +296,5 @@ fn ser_unnamed_enum() { let content = "84"; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); } diff --git a/yaserde/tests/flatten.rs b/yaserde/tests/flatten.rs index 33e0293..71274d6 100644 --- a/yaserde/tests/flatten.rs +++ b/yaserde/tests/flatten.rs @@ -9,7 +9,7 @@ use yaserde::{YaDeserialize, YaSerialize}; #[test] fn basic_flatten() { - #[derive(Default, PartialEq, Debug, YaSerialize)] + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] struct DateTime { #[yaserde(flatten)] date: Date, @@ -18,7 +18,7 @@ fn basic_flatten() { kind: DateKind, } - #[derive(Default, PartialEq, Debug, YaSerialize)] + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] struct Date { year: i32, month: i32, @@ -29,18 +29,18 @@ fn basic_flatten() { optional_extra: Option, } - #[derive(Default, PartialEq, Debug, YaSerialize)] + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] pub struct Extra { week: i32, century: i32, } - #[derive(Default, PartialEq, Debug, YaSerialize)] + #[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] pub struct OptionalExtra { lunar_day: i32, } - #[derive(PartialEq, Debug, YaSerialize)] + #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)] pub enum DateKind { #[yaserde(rename = "holidays")] Holidays(Vec), @@ -88,6 +88,7 @@ fn basic_flatten() { "#; serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, DateTime); } #[test] diff --git a/yaserde/tests/namespace.rs b/yaserde/tests/namespace.rs new file mode 100644 index 0000000..4025e90 --- /dev/null +++ b/yaserde/tests/namespace.rs @@ -0,0 +1,442 @@ +#[macro_use] +extern crate yaserde; +#[macro_use] +extern crate yaserde_derive; + +use std::io::{Read, Write}; +use yaserde::{YaDeserialize, YaSerialize}; + +#[test] +fn struct_simple_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "book", + prefix = "ns", + namespace = "ns: http://www.sample.com/ns/domain" + )] + pub struct Book { + #[yaserde(prefix = "ns")] + author: String, + #[yaserde(prefix = "ns")] + title: String, + } + + let content = r#" + + Antoine de Saint-Exupéry + Little prince + + "#; + + let model = Book { + author: String::from("Antoine de Saint-Exupéry"), + title: String::from("Little prince"), + }; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, Book); +} + +#[test] +fn struct_multiple_namespaces() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "book", + prefix = "ns", + namespace = "ns: http://www.sample.com/ns/domain", + namespace = "ns2: http://www.sample.com/ns/domain_2" + )] + pub struct Book { + #[yaserde(prefix = "ns")] + author: String, + #[yaserde(prefix = "ns2")] + title: String, + } + + let content = r#" + + Antoine de Saint-Exupéry + Little prince + + "#; + + let model = Book { + author: String::from("Antoine de Saint-Exupéry"), + title: String::from("Little prince"), + }; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, Book); +} + +#[test] +fn struct_partial_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "book", + prefix = "ns", + namespace = "ns: http://www.sample.com/ns/domain" + )] + pub struct Book { + author: String, + #[yaserde(prefix = "ns")] + title: String, + } + + let content = r#" + + Antoine de Saint-Exupéry + Little prince + + "#; + + let model = Book { + author: String::from("Antoine de Saint-Exupéry"), + title: String::from("Little prince"), + }; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, Book); +} + +#[test] +fn struct_sub_namespace_definition() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "book", + prefix = "ns", + namespace = "ns: http://www.sample.com/ns/domain", + namespace = "ns2: http://www.sample.com/ns/domain_2" + )] + pub struct Book { + #[yaserde(prefix = "ns")] + author: String, + #[yaserde(prefix = "ns2", namespace = "ns2: http://www.sample.com/ns/domain_2")] + title: String, + } + + let content = r#" + + Antoine de Saint-Exupéry + Little prince + + "#; + + let model = Book { + author: String::from("Antoine de Saint-Exupéry"), + title: String::from("Little prince"), + }; + + // TODO support namespace for attribute to specify local namespace + // serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, Book); +} + +#[test] +fn struct_namespace_nested() { + #[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")] + struct A { + #[yaserde(prefix = "nsa")] + alpha: i32, + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(prefix = "nsb", namespace = "nsb: http://www.sample.com/ns/b")] + struct B { + // Note that name `nested` resides in `nsb` though it has a type from `nsa` + #[yaserde(prefix = "nsb")] + nested: A, + } + + let content = r#" + + + 32 + + + "#; + + let model = B { + nested: A { alpha: 32 }, + }; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, B); +} + +#[test] +fn struct_namespace_nested_defined_at_root() { + #[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")] + struct A { + #[yaserde(prefix = "nsa")] + alpha: i32, + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + prefix = "nsb", + namespace = "nsb: http://www.sample.com/ns/b" + namespace = "nsa: http://www.sample.com/ns/a" + )] + struct B { + // Note that name `nested` resides in `nsb` though it has a type from `nsa` + #[yaserde(prefix = "nsb")] + nested: A, + } + + let content = r#" + + + 32 + + + "#; + + let model = B { + nested: A { alpha: 32 }, + }; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, B); +} + +#[test] +fn struct_attribute_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "root", + namespace = "ns1: http://www.sample.com/ns/domain1", + namespace = "ns2: http://www.sample.com/ns/domain2" + )] + pub struct XmlStruct { + #[yaserde(prefix = "ns1")] + item_1: String, + #[yaserde(attribute, prefix = "ns2")] + item_2: String, + } + + let model = XmlStruct { + item_1: "something 1".to_string(), + item_2: "something 2".to_string(), + }; + + let content = r#" + + something 1 + + "#; + + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn struct_implicit_default_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "tt", + namespace = "http://www.w3.org/ns/ttml", + namespace = "ttm: http://www.w3.org/ns/ttml#metadata" + )] + pub struct XmlStruct { + item: String, + } + + let model = XmlStruct { + item: "something".to_string(), + }; + + let content = r#"something"#; + serialize_and_validate!(model, content); + // TODO + // deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn struct_explicit_default_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "tt", + default_namespace = "ttml", + namespace = "ttml: http://www.w3.org/ns/ttml", + namespace = "ttm: http://www.w3.org/ns/ttml#metadata" + )] + pub struct XmlStruct { + item: String, + } + + let model = XmlStruct { + item: "something".to_string(), + }; + + let content = r#"something"#; + serialize_and_validate!(model, content); + // TODO + // deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn struct_default_namespace_via_attribute_with_prefix() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "tt", + prefix = "TTML", + default_namespace = "TTML", + namespace = "TTML: http://www.w3.org/ns/ttml", + namespace = "ttm: http://www.w3.org/ns/ttml#metadata" + )] + pub struct XmlStruct { + #[yaserde(prefix = "TTML")] + item: String, + } + + let model = XmlStruct { + item: "something".to_string(), + }; + + let content = r#"something"#; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn enum_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "root", + prefix = "ns", + namespace = "ns: http://www.sample.com/ns/domain" + )] + pub enum XmlStruct { + #[yaserde(prefix = "ns")] + Item, + } + + impl Default for XmlStruct { + fn default() -> XmlStruct { + XmlStruct::Item + } + } + + let content = r#" + + ns:Item + + "#; + + let model = XmlStruct::Item; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn enum_multi_namespaces() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "root", + namespace = "ns1: http://www.sample.com/ns/domain1", + namespace = "ns2: http://www.sample.com/ns/domain2" + )] + pub enum XmlStruct { + #[yaserde(prefix = "ns1")] + Item1, + #[yaserde(prefix = "ns2")] + Item2, + } + + impl Default for XmlStruct { + fn default() -> XmlStruct { + XmlStruct::Item1 + } + } + + let model = XmlStruct::Item1; + let content = r#" + + ns1:Item1 + + "#; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); + + let model = XmlStruct::Item2; + let content = r#" + + ns2:Item2 + + "#; + serialize_and_validate!(model, content); + // TODO + // deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn enum_attribute_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "root", + prefix = "ns", + namespace = "ns: http://www.sample.com/ns/domain" + )] + pub enum XmlStruct { + #[yaserde(prefix = "ns")] + Item, + #[yaserde(prefix = "ns")] + ItemWithField(String), + } + + impl Default for XmlStruct { + fn default() -> XmlStruct { + XmlStruct::Item + } + } + + let content = r#" + + ns:Item + + "#; + + let model = XmlStruct::Item; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); + + let model = XmlStruct::ItemWithField("Value".to_string()); + + let content = r#"Value"#; + serialize_and_validate!(model, content); + // TODO + // deserialize_and_validate!(content, model, XmlStruct); +} + +#[test] +fn struct_bad_namespace() { + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde( + root = "book", + prefix = "ns", + namespace = "ns: http://www.sample.com/ns/domain", + namespace = "ns2: http://www.sample.com/ns/domain_2" + )] + pub struct Book { + #[yaserde(prefix = "ns")] + author: String, + #[yaserde(prefix = "ns2", namespace = "ns2: http://www.sample.com/ns/domain_2")] + title: String, + } + + let content = r#" + + Antoine de Saint-Exupéry + Little prince + + "#; + + let loaded: Result = yaserde::de::from_str(content); + assert_eq!( + loaded, + Err("bad namespace for book, found http://www.sample.com/ns/domain2".to_string()) + ); +} diff --git a/yaserde/tests/ser_flatten.rs b/yaserde/tests/ser_flatten.rs deleted file mode 100644 index b4c04ec..0000000 --- a/yaserde/tests/ser_flatten.rs +++ /dev/null @@ -1,139 +0,0 @@ -#[macro_use] -extern crate yaserde; -#[macro_use] -extern crate yaserde_derive; - -use std::io::Write; -use yaserde::YaSerialize; - -#[test] -fn ser_flatten() { - #[derive(Default, PartialEq, Debug, YaSerialize)] - struct DateTime { - #[yaserde(flatten)] - date: Date, - time: String, - #[yaserde(flatten)] - kind: DateKind, - } - - #[derive(Default, PartialEq, Debug, YaSerialize)] - struct Date { - year: i32, - month: i32, - day: i32, - #[yaserde(flatten)] - extra: Extra, - #[yaserde(flatten)] - optional_extra: Option, - } - - #[derive(Default, PartialEq, Debug, YaSerialize)] - pub struct Extra { - week: i32, - century: i32, - } - - #[derive(Default, PartialEq, Debug, YaSerialize)] - pub struct OptionalExtra { - lunar_day: i32, - } - - #[derive(PartialEq, Debug, YaSerialize)] - pub enum DateKind { - #[yaserde(rename = "holidays")] - Holidays(Vec), - #[yaserde(rename = "working")] - Working, - } - - impl Default for DateKind { - fn default() -> Self { - DateKind::Working - } - }; - - let model = DateTime { - date: Date { - year: 2020, - month: 1, - day: 1, - extra: Extra { - week: 1, - century: 21, - }, - optional_extra: Some(OptionalExtra { lunar_day: 1 }), - }, - time: "10:40:03".to_string(), - kind: DateKind::Holidays(vec![ - "New Year's Day".into(), - "Novy God Day".into(), - "Polar Bear Swim Day".into(), - ]), - }; - - let content = r#" - - 2020 - 1 - 1 - 1 - 21 - 1 - - New Year's Day - Novy God Day - Polar Bear Swim Day - "#; - - serialize_and_validate!(model, content); -} - -#[test] -fn ser_root_flatten_struct() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(flatten)] - pub struct Content { - binary_data: String, - string_data: String, - } - - let model = Content { - binary_data: "binary".to_string(), - string_data: "string".to_string(), - }; - let content = "binarystring"; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_root_flatten_enum() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(flatten)] - pub enum Content { - Binary(Binary), - Data(Data), - } - - #[derive(YaSerialize, PartialEq, Debug)] - pub struct Binary { - binary_data: String, - } - - #[derive(YaSerialize, PartialEq, Debug)] - pub struct Data { - string_data: String, - } - - let model = Content::Binary(Binary { - binary_data: "binary".to_string(), - }); - let content = "binary"; - serialize_and_validate!(model, content); - - let model = Content::Data(Data { - string_data: "string".to_string(), - }); - let content = "string"; - serialize_and_validate!(model, content); -} diff --git a/yaserde/tests/ser_namespace.rs b/yaserde/tests/ser_namespace.rs deleted file mode 100644 index 906735b..0000000 --- a/yaserde/tests/ser_namespace.rs +++ /dev/null @@ -1,221 +0,0 @@ -#[macro_use] -extern crate yaserde; -#[macro_use] -extern crate yaserde_derive; - -use std::io::Write; -use yaserde::YaSerialize; - -#[test] -fn ser_struct_namespace() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "root", - prefix = "ns", - namespace = "ns: http://www.sample.com/ns/domain" - )] - pub struct XmlStruct { - #[yaserde(prefix = "ns")] - item: String, - } - - let model = XmlStruct { - item: "something".to_string(), - }; - - let content = - r#"something"#; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_enum_namespace() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "root", - prefix = "ns", - namespace = "ns: http://www.sample.com/ns/domain" - )] - pub enum XmlStruct { - #[yaserde(prefix = "ns")] - Item, - #[yaserde(prefix = "ns")] - ItemWithField(String), - } - - let model = XmlStruct::Item; - - let content = r#"ns:Item"#; - serialize_and_validate!(model, content); - - let model = XmlStruct::ItemWithField("Value".to_string()); - - let content = r#"Value"#; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_struct_multi_namespace() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "root", - namespace = "ns1: http://www.sample.com/ns/domain1", - namespace = "ns2: http://www.sample.com/ns/domain2" - )] - pub struct XmlStruct { - #[yaserde(prefix = "ns1")] - item_1: String, - #[yaserde(prefix = "ns2")] - item_2: String, - } - - let model = XmlStruct { - item_1: "something 1".to_string(), - item_2: "something 2".to_string(), - }; - - let content = r#"something 1something 2"#; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_enum_multi_namespace() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "root", - namespace = "ns1: http://www.sample.com/ns/domain1", - namespace = "ns2: http://www.sample.com/ns/domain2" - )] - pub enum XmlStruct { - #[yaserde(prefix = "ns1")] - Item1, - #[yaserde(prefix = "ns2")] - Item2, - } - - let model1 = XmlStruct::Item1; - let content = r#"ns1:Item1"#; - serialize_and_validate!(model1, content); - let model2 = XmlStruct::Item2; - let content = r#"ns2:Item2"#; - serialize_and_validate!(model2, content); -} - -#[test] -fn ser_struct_attribute_namespace() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "root", - namespace = "ns1: http://www.sample.com/ns/domain1", - namespace = "ns2: http://www.sample.com/ns/domain2" - )] - pub struct XmlStruct { - #[yaserde(prefix = "ns1")] - item_1: String, - #[yaserde(attribute, prefix = "ns2")] - item_2: String, - } - - let model = XmlStruct { - item_1: "something 1".to_string(), - item_2: "something 2".to_string(), - }; - - let content = r#"something 1"#; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_struct_default_namespace() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "tt", - namespace = "http://www.w3.org/ns/ttml", - namespace = "ttm: http://www.w3.org/ns/ttml#metadata" - )] - pub struct XmlStruct { - item: String, - } - - let model = XmlStruct { - item: "something".to_string(), - }; - - let content = r#"something"#; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_struct_default_namespace_via_attribute() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "tt", - default_namespace = "ttml", - namespace = "ttml: http://www.w3.org/ns/ttml", - namespace = "ttm: http://www.w3.org/ns/ttml#metadata" - )] - pub struct XmlStruct { - item: String, - } - - let model = XmlStruct { - item: "something".to_string(), - }; - - let content = r#"something"#; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_struct_default_namespace_via_attribute_with_prefix() { - #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde( - root = "tt", - prefix = "TTML", - default_namespace = "TTML", - namespace = "TTML: http://www.w3.org/ns/ttml", - namespace = "ttm: http://www.w3.org/ns/ttml#metadata" - )] - pub struct XmlStruct { - #[yaserde(prefix = "TTML")] - item: String, - } - - let model = XmlStruct { - item: "something".to_string(), - }; - - let content = r#"something"#; - serialize_and_validate!(model, content); -} - -#[test] -fn ser_struct_namespace_nested() { - #[derive(YaSerialize, Default, PartialEq, Debug)] - #[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")] - struct A { - #[yaserde(prefix = "nsa")] - alpha: i32, - } - - #[derive(YaSerialize, Default, PartialEq, Debug)] - #[yaserde(prefix = "nsb", namespace = "nsb: http://www.sample.com/ns/b")] - struct B { - // Note that name `nested` resides in `nsb` though it has a type from `nsa` - #[yaserde(prefix = "nsb")] - nested: A, - } - - serialize_and_validate!( - B { - nested: A { alpha: 32 } - }, - r#" - - - 32 - - - "# - ); -} diff --git a/yaserde/tests/ser_skip.rs b/yaserde/tests/skip_if.rs similarity index 96% rename from yaserde/tests/ser_skip.rs rename to yaserde/tests/skip_if.rs index 05cb74b..ad6f9de 100644 --- a/yaserde/tests/ser_skip.rs +++ b/yaserde/tests/skip_if.rs @@ -7,7 +7,7 @@ use std::io::Write; use yaserde::YaSerialize; #[test] -fn ser_skip_serializing_if_for_struct() { +fn skip_serializing_if_for_struct() { #[derive(YaSerialize, PartialEq, Debug)] #[yaserde(root = "base")] pub struct XmlStruct { From 04ddaa29dcb39cd7887e9fec35fcb433f2c334c0 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Tue, 21 Apr 2020 15:02:34 +0200 Subject: [PATCH 3/7] restructure code --- yaserde_derive/src/{ => common}/attribute.rs | 0 yaserde_derive/src/common/field.rs | 168 ++++++++++++++++ yaserde_derive/src/common/mod.rs | 5 + yaserde_derive/src/de/expand_enum.rs | 55 +++--- yaserde_derive/src/de/expand_struct.rs | 127 ++++++------ yaserde_derive/src/de/mod.rs | 4 +- yaserde_derive/src/field_type.rs | 102 ---------- yaserde_derive/src/lib.rs | 3 +- yaserde_derive/src/ser/element.rs | 2 +- yaserde_derive/src/ser/expand_enum.rs | 74 +++---- yaserde_derive/src/ser/expand_struct.rs | 187 +++++++++--------- .../src/ser/implement_deserializer.rs | 2 +- yaserde_derive/src/ser/label.rs | 2 +- yaserde_derive/src/ser/mod.rs | 2 +- yaserde_derive/src/ser/namespace.rs | 2 +- 15 files changed, 391 insertions(+), 344 deletions(-) rename yaserde_derive/src/{ => common}/attribute.rs (100%) create mode 100644 yaserde_derive/src/common/field.rs create mode 100644 yaserde_derive/src/common/mod.rs delete mode 100644 yaserde_derive/src/field_type.rs diff --git a/yaserde_derive/src/attribute.rs b/yaserde_derive/src/common/attribute.rs similarity index 100% rename from yaserde_derive/src/attribute.rs rename to yaserde_derive/src/common/attribute.rs diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs new file mode 100644 index 0000000..6e01569 --- /dev/null +++ b/yaserde_derive/src/common/field.rs @@ -0,0 +1,168 @@ +use crate::common::attribute::YaSerdeAttribute; +use proc_macro2::{Ident, TokenStream}; +use std::fmt; +use syn; +use syn::Type::Path; + +#[derive(Debug)] +pub enum Field { + FieldString, + FieldBool, + FieldI8, + FieldU8, + FieldI16, + FieldU16, + FieldI32, + FieldU32, + FieldI64, + FieldU64, + FieldF32, + FieldF64, + FieldOption { data_type: Box }, + FieldVec { data_type: Box }, + FieldStruct { struct_name: syn::Path }, +} + +impl Field { + pub fn is_attribute(token_field: &syn::Field) -> bool { + YaSerdeAttribute::parse(&token_field.attrs).attribute + } + + pub fn is_text_content(token_field: &syn::Field) -> bool { + YaSerdeAttribute::parse(&token_field.attrs).text + } + + pub fn label(token_field: &syn::Field) -> Option { + token_field.ident.clone() + } + + pub fn renamed_label(token_field: &syn::Field, root_attributes: &YaSerdeAttribute) -> String { + let attributes = YaSerdeAttribute::parse(&token_field.attrs); + + let prefix = if root_attributes.default_namespace == attributes.prefix { + "".to_string() + } else { + attributes + .prefix + .clone() + .map_or("".to_string(), |prefix| prefix + ":") + }; + + let label = attributes + .rename + .clone() + .unwrap_or_else(|| token_field.ident.as_ref().unwrap().to_string()); + + format!("{}{}", prefix, label) + } + + pub fn get_simple_type_visitor(&self) -> TokenStream { + let ident = format_ident!("visit_{}", self.to_string()); + quote! {#ident} + } +} + +impl From<&syn::Path> for Field { + fn from(path: &syn::Path) -> Self { + let result = if let Some(segment) = path.segments.last() { + match segment.ident.to_string().as_str() { + "String" => Some(Field::FieldString), + "bool" => Some(Field::FieldBool), + "i8" => Some(Field::FieldI8), + "u8" => Some(Field::FieldU8), + "i16" => Some(Field::FieldI16), + "u16" => Some(Field::FieldU16), + "i32" => Some(Field::FieldI32), + "u32" => Some(Field::FieldU32), + "i64" => Some(Field::FieldI64), + "u64" => Some(Field::FieldU64), + "f32" => Some(Field::FieldF32), + "f64" => Some(Field::FieldF64), + "Option" => Some(Field::FieldOption { + data_type: Box::new(Field::from(segment)), + }), + "Vec" => Some(Field::FieldVec { + data_type: Box::new(Field::from(segment)), + }), + _ => None, + } + } else { + None + }; + + result.unwrap_or_else(|| Field::FieldStruct { + struct_name: path.clone(), + }) + } +} + +impl From<&syn::Field> for Field { + fn from(field: &syn::Field) -> Self { + match field.ty { + Path(ref path) => Field::from(&path.path), + _ => panic!("unable to match {:?}", field.ty), + } + } +} + +impl From<&syn::PathSegment> for Field { + fn from(path_segment: &syn::PathSegment) -> Self { + if let syn::PathArguments::AngleBracketed(ref args) = path_segment.arguments { + if let Some(tt) = args.args.first() { + if let syn::GenericArgument::Type(ref argument) = *tt { + if let Path(ref path) = *argument { + return Field::from(&path.path); + } + } + } + } + unimplemented!() + } +} + +impl Into for Field { + fn into(self) -> proc_macro2::TokenStream { + match self { + Field::FieldString => quote! {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}, + _ => panic!("Not a simple type: {:?}", self), + } + } +} + +impl Into for &Field { + fn into(self) -> String { + match self { + Field::FieldString => "str".to_string(), + Field::FieldBool => "bool".to_string(), + Field::FieldI8 => "i8".to_string(), + Field::FieldU8 => "u8".to_string(), + Field::FieldI16 => "i16".to_string(), + Field::FieldU16 => "u16".to_string(), + Field::FieldI32 => "i32".to_string(), + Field::FieldU32 => "u32".to_string(), + Field::FieldI64 => "i64".to_string(), + Field::FieldU64 => "u64".to_string(), + Field::FieldF32 => "f32".to_string(), + Field::FieldF64 => "f64".to_string(), + _ => panic!("Not a simple type: {:?}", self), + } + } +} + +impl fmt::Display for Field { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let string_representation: String = self.into(); + write!(f, "{}", string_representation) + } +} diff --git a/yaserde_derive/src/common/mod.rs b/yaserde_derive/src/common/mod.rs new file mode 100644 index 0000000..2dc2de9 --- /dev/null +++ b/yaserde_derive/src/common/mod.rs @@ -0,0 +1,5 @@ +mod attribute; +mod field; + +pub use attribute::YaSerdeAttribute; +pub use field::Field; diff --git a/yaserde_derive/src/de/expand_enum.rs b/yaserde_derive/src/de/expand_enum.rs index c43d246..c1efe82 100644 --- a/yaserde_derive/src/de/expand_enum.rs +++ b/yaserde_derive/src/de/expand_enum.rs @@ -1,10 +1,11 @@ -use crate::attribute::*; -use crate::field_type::*; +use crate::common::{Field, YaSerdeAttribute}; use proc_macro2::TokenStream; -use syn::spanned::Spanned; -use syn::DataEnum; -use syn::Fields; -use syn::Ident; +use syn::{ + spanned::Spanned, + DataEnum, + Fields, + Ident, +}; pub fn parse( data_enum: &DataEnum, @@ -160,9 +161,9 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { }) }; - let simple_type_visitor = |simple_type| { - let field_type = get_simple_type_token(&simple_type); - let visitor = get_simple_type_visitor(&simple_type); + let simple_type_visitor = |simple_type: Field| { + let visitor = simple_type.get_simple_type_visitor(); + let field_type = simple_type.into(); make_visitor( &visitor, @@ -171,8 +172,8 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { ) }; - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeStruct { struct_name } => { + match Field::from(field) { + Field::FieldStruct { struct_name } => { let struct_id: String = struct_name .segments .iter() @@ -189,14 +190,12 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { }, ) } - FieldType::FieldTypeOption { data_type } | FieldType::FieldTypeVec { data_type } => { - match *data_type { - FieldType::FieldTypeStruct { .. } => None, - simple_type => simple_type_visitor(simple_type), - } - } + Field::FieldOption { data_type } | Field::FieldVec { data_type } => match *data_type { + Field::FieldStruct { .. } => None, + simple_type => simple_type_visitor(simple_type), + }, simple_type => simple_type_visitor(simple_type), - }) + } }) .filter_map(|f| f) .collect() @@ -213,9 +212,9 @@ fn build_unnamed_visitor_calls( .map(|(idx, field)| { let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span()); - let call_simple_type_visitor = |simple_type, action| { - let field_type = get_simple_type_token(&simple_type); - let visitor = get_simple_type_visitor(&simple_type); + let call_simple_type_visitor = |simple_type: Field, action| { + let visitor = simple_type.get_simple_type_visitor(); + let field_type: TokenStream = simple_type.into(); let label_name = format!("field_{}", idx); @@ -279,19 +278,19 @@ fn build_unnamed_visitor_calls( } }; - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeStruct { struct_name } => call_struct_visitor(struct_name, set_val), - FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeStruct { struct_name } => call_struct_visitor(struct_name, set_opt), + match Field::from(field) { + Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_val), + Field::FieldOption { data_type } => match *data_type { + Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_opt), simple_type => call_simple_type_visitor(simple_type, set_opt), }, - FieldType::FieldTypeVec { data_type } => match *data_type { - FieldType::FieldTypeStruct { struct_name } => call_struct_visitor(struct_name, set_vec), + Field::FieldVec { data_type } => match *data_type { + Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_vec), simple_type => call_simple_type_visitor(simple_type, set_vec), }, simple_type => call_simple_type_visitor(simple_type, set_val), - }) + } }) .filter_map(|f| f) .collect() diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 3c48215..4066e62 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -1,11 +1,12 @@ -use crate::attribute::*; +use crate::common::{Field, YaSerdeAttribute}; use crate::de::build_default_value::build_default_value; -use crate::field_type::*; use proc_macro2::{Span, TokenStream}; use std::collections::BTreeMap; -use syn::spanned::Spanned; -use syn::DataStruct; -use syn::Ident; +use syn::{ + spanned::Spanned, + DataStruct, + Ident, +}; pub fn parse( data_struct: &DataStruct, @@ -33,14 +34,14 @@ pub fn parse( let label = &get_value_label(&field.ident); let field_attrs = YaSerdeAttribute::parse(&field.attrs); - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeStruct { struct_name } => build_default_value( + match Field::from(field) { + Field::FieldStruct { struct_name } => build_default_value( label, "e! {#struct_name}, "e! {#struct_name::default()}, &field_attrs.default, ), - FieldType::FieldTypeOption { .. } => { + Field::FieldOption { .. } => { if let Some(d) = &field_attrs.default { let default_function = Ident::new(&d, field.span()); @@ -55,18 +56,18 @@ pub fn parse( }) } } - FieldType::FieldTypeVec { data_type } => match *data_type { - FieldType::FieldTypeStruct { ref struct_name } => build_default_value( + Field::FieldVec { data_type } => match *data_type { + Field::FieldStruct { ref struct_name } => build_default_value( label, "e! {Vec<#struct_name>}, "e! {vec![]}, &field_attrs.default, ), - FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => { + Field::FieldOption { .. } | Field::FieldVec { .. } => { unimplemented!(); } simple_type => { - let type_token = get_simple_type_token(&simple_type); + let type_token: TokenStream = simple_type.into(); build_default_value( label, @@ -77,7 +78,8 @@ pub fn parse( } }, simple_type => { - let type_token = get_simple_type_token(&simple_type); + let type_token: TokenStream = simple_type.into(); + build_default_value( label, &type_token, @@ -85,7 +87,7 @@ pub fn parse( &field_attrs.default, ) } - }) + } }) .filter_map(|x| x) .collect(); @@ -123,10 +125,10 @@ pub fn parse( }) }; - let simple_type_visitor = |simple_type: FieldType| { - let field_type = get_simple_type_token(&simple_type); - let visitor = get_simple_type_visitor(&simple_type); + let simple_type_visitor = |simple_type: Field| { + let visitor = simple_type.get_simple_type_visitor(); let visitor_label = build_visitor_ident(&label_name, field.span(), None); + let field_type: TokenStream = simple_type.into(); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -141,20 +143,20 @@ pub fn parse( }) }; - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeStruct { struct_name } => struct_visitor(struct_name), - FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeStruct { struct_name } => struct_visitor(struct_name), - FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => None, + match Field::from(field) { + Field::FieldStruct { struct_name } => struct_visitor(struct_name), + Field::FieldOption { data_type } => match *data_type { + Field::FieldStruct { struct_name } => struct_visitor(struct_name), + Field::FieldOption { .. } | Field::FieldVec { .. } => None, simple_type => simple_type_visitor(simple_type), }, - FieldType::FieldTypeVec { data_type } => match *data_type { - FieldType::FieldTypeStruct { struct_name } => struct_visitor(struct_name), - FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => None, + Field::FieldVec { data_type } => match *data_type { + Field::FieldStruct { struct_name } => struct_visitor(struct_name), + Field::FieldOption { .. } | Field::FieldVec { .. } => None, simple_type => simple_type_visitor(simple_type), }, simple_type => simple_type_visitor(simple_type), - }) + } }) .filter_map(|x| x) .collect(); @@ -192,10 +194,12 @@ pub fn parse( }) }; - let visit_simple = |simple_type: FieldType, action: TokenStream| { + let visit_simple = |simple_type: Field, action: TokenStream| { + let field_visitor = simple_type.get_simple_type_visitor(); + let field_type: TokenStream = simple_type.into(); build_call_visitor( - &get_simple_type_token(&simple_type), - &get_simple_type_visitor(&simple_type), + &field_type, + &field_visitor, &action, &field_attrs, label, @@ -204,18 +208,18 @@ pub fn parse( ) }; - let visit_sub = |sub_type: Box, action: TokenStream| match *sub_type { - FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => unimplemented!(), - FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, action), + let visit_sub = |sub_type: Box, action: TokenStream| match *sub_type { + Field::FieldOption { .. } | Field::FieldVec { .. } => unimplemented!(), + Field::FieldStruct { struct_name } => visit_struct(struct_name, action), simple_type => visit_simple(simple_type, action), }; - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, quote! {= value}), - FieldType::FieldTypeOption { data_type } => visit_sub(data_type, quote! {= Some(value)}), - FieldType::FieldTypeVec { data_type } => visit_sub(data_type, quote! {.push(value)}), + match Field::from(field) { + Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}), + Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}), + Field::FieldVec { data_type } => visit_sub(data_type, quote! {.push(value)}), simple_type => visit_simple(simple_type, quote! {= value}), - }) + } }) .filter_map(|x| x) .collect(); @@ -231,18 +235,18 @@ pub fn parse( return None; } - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeStruct { .. } => Some(quote! { + match Field::from(field) { + Field::FieldStruct { .. } => Some(quote! { #value_label = yaserde::de::from_str(&unused_xml_elements)?; }), - FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeStruct { .. } => Some(quote! { + Field::FieldOption { data_type } => match *data_type { + Field::FieldStruct { .. } => Some(quote! { #value_label = yaserde::de::from_str(&unused_xml_elements).ok(); }), field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type), }, field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type), - }) + } }) .filter_map(|x| x) .collect(); @@ -294,27 +298,27 @@ pub fn parse( ) }; - let visit_simple = |simple_type: FieldType, action: TokenStream| { + let visit_simple = |simple_type: Field, action: TokenStream| { visit( &action, - &get_simple_type_visitor(&simple_type), + &simple_type.get_simple_type_visitor(), &visitor_label, ) }; - let visit_sub = |sub_type: Box, action: TokenStream| match *sub_type { - FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => unimplemented!(), - FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, action), + let visit_sub = |sub_type: Box, action: TokenStream| match *sub_type { + Field::FieldOption { .. } | Field::FieldVec { .. } => unimplemented!(), + Field::FieldStruct { struct_name } => visit_struct(struct_name, action), simple_type => visit_simple(simple_type, action), }; - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeString => visit_string(), - FieldType::FieldTypeOption { data_type } => visit_sub(data_type, quote! {= Some(value)}), - FieldType::FieldTypeVec { .. } => unimplemented!(), - FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, quote! {= value}), + match Field::from(field) { + Field::FieldString => visit_string(), + Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}), + Field::FieldVec { .. } => unimplemented!(), + Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}), simple_type => visit_simple(simple_type, quote! {= value}), - }) + } }) .filter_map(|x| x) .collect(); @@ -334,16 +338,14 @@ pub fn parse( } }; - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeString => set_text("e! {text_content.to_owned()}), - FieldType::FieldTypeStruct { .. } - | FieldType::FieldTypeOption { .. } - | FieldType::FieldTypeVec { .. } => None, + match Field::from(field) { + Field::FieldString => set_text("e! {text_content.to_owned()}), + Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None, simple_type => { - let type_token = get_simple_type_token(&simple_type); + let type_token: TokenStream = simple_type.into(); set_text("e! {#type_token::from_str(text_content).unwrap()}) } - }) + } }) .filter_map(|x| x) .collect(); @@ -355,11 +357,8 @@ pub fn parse( let label = &field.ident; let value_label = &get_value_label(&field.ident); - get_field_type(field).map(|_| { - quote! { #label: #value_label, } - }) + quote! { #label: #value_label, } }) - .filter_map(|x| x) .collect(); let (init_unused, write_unused, visit_unused) = if call_flatten_visitors.is_empty() { diff --git a/yaserde_derive/src/de/mod.rs b/yaserde_derive/src/de/mod.rs index 84f1f17..ec9ff56 100644 --- a/yaserde_derive/src/de/mod.rs +++ b/yaserde_derive/src/de/mod.rs @@ -2,7 +2,7 @@ pub mod build_default_value; pub mod expand_enum; pub mod expand_struct; -use crate::attribute; +use crate::common::YaSerdeAttribute; use proc_macro2::TokenStream; use syn; use syn::Ident; @@ -12,7 +12,7 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result }, - FieldTypeVec { data_type: Box }, - FieldTypeStruct { struct_name: syn::Path }, -} - -impl FieldType { - fn from_ident(path: &syn::Path) -> Option { - match path.segments.last() { - Some(t) => match t.ident.to_string().as_str() { - "String" => Some(FieldType::FieldTypeString), - "bool" => Some(FieldType::FieldTypeBool), - "i8" => Some(FieldType::FieldTypeI8), - "u8" => Some(FieldType::FieldTypeU8), - "i16" => Some(FieldType::FieldTypeI16), - "u16" => Some(FieldType::FieldTypeU16), - "i32" => Some(FieldType::FieldTypeI32), - "u32" => Some(FieldType::FieldTypeU32), - "i64" => Some(FieldType::FieldTypeI64), - "u64" => Some(FieldType::FieldTypeU64), - "f32" => Some(FieldType::FieldTypeF32), - "f64" => Some(FieldType::FieldTypeF64), - "Option" => get_sub_type(t).map(|data_type| FieldType::FieldTypeOption { - data_type: Box::new(FieldType::from_ident(&data_type).unwrap()), - }), - "Vec" => get_sub_type(t).map(|data_type| FieldType::FieldTypeVec { - data_type: Box::new(FieldType::from_ident(&data_type).unwrap()), - }), - _ => Some(FieldType::FieldTypeStruct { - struct_name: path.clone(), - }), - }, - _ => None, - } - } -} - -pub fn get_field_type(field: &syn::Field) -> Option { - match field.ty { - Path(ref path) => FieldType::from_ident(&path.path), - _ => None, - } -} - -fn get_sub_type(t: &syn::PathSegment) -> Option { - if let syn::PathArguments::AngleBracketed(ref args) = t.arguments { - if let Some(tt) = args.args.first() { - if let syn::GenericArgument::Type(ref argument) = *tt { - if let Path(ref path) = *argument { - return Some(path.path.clone()); - } - } - } - } - - None -} - -pub fn get_simple_type_token(field_type: &FieldType) -> proc_macro2::TokenStream { - match field_type { - FieldType::FieldTypeString => quote! {String}, - FieldType::FieldTypeBool => quote! {bool}, - FieldType::FieldTypeI8 => quote! {i8}, - FieldType::FieldTypeU8 => quote! {u8}, - FieldType::FieldTypeI16 => quote! {i16}, - FieldType::FieldTypeU16 => quote! {u16}, - FieldType::FieldTypeI32 => quote! {i32}, - FieldType::FieldTypeU32 => quote! {u32}, - FieldType::FieldTypeI64 => quote! {i64}, - FieldType::FieldTypeU64 => quote! {u64}, - FieldType::FieldTypeF32 => quote! {f32}, - FieldType::FieldTypeF64 => quote! {f64}, - _ => panic!("Not a simple type: {:?}", field_type), - } -} - -pub fn get_simple_type_visitor(field_type: &FieldType) -> proc_macro2::TokenStream { - let ident = format_ident!( - "visit_{}", - get_simple_type_token(field_type) - .to_string() - .replace("String", "str") - ); - - quote! {#ident} -} diff --git a/yaserde_derive/src/lib.rs b/yaserde_derive/src/lib.rs index 527a439..7fd17fa 100644 --- a/yaserde_derive/src/lib.rs +++ b/yaserde_derive/src/lib.rs @@ -6,9 +6,8 @@ extern crate proc_macro2; extern crate quote; extern crate syn; -mod attribute; +mod common; mod de; -mod field_type; mod ser; use proc_macro::TokenStream; diff --git a/yaserde_derive/src/ser/element.rs b/yaserde_derive/src/ser/element.rs index 313be33..65e5c44 100644 --- a/yaserde_derive/src/ser/element.rs +++ b/yaserde_derive/src/ser/element.rs @@ -1,4 +1,4 @@ -use crate::attribute::*; +use crate::common::YaSerdeAttribute; use proc_macro2::{Ident, Span, TokenStream}; pub fn enclose_formatted_characters(label: &Ident, label_name: String) -> TokenStream { diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index fb42821..cb85a93 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -1,8 +1,6 @@ -use crate::attribute::*; -use crate::field_type::*; +use crate::common::{Field, YaSerdeAttribute}; use crate::ser::{implement_deserializer::implement_deserializer, label::build_label_name}; use proc_macro2::TokenStream; -use syn::spanned::Spanned; use syn::DataEnum; use syn::Fields; use syn::Ident; @@ -52,38 +50,34 @@ fn inner_enum_inspector( .named .iter() .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - if field_attrs.attribute { + if Field::is_attribute(field) { return None; } - let field_label = &field.ident; - if field_attrs.text { + let field_label = Field::label(field); + + if Field::is_text_content(field) { return Some(quote!( let data_event = XmlEvent::characters(&self.#field_label); writer.write(data_event).map_err(|e| e.to_string())?; )); } - let renamed_field_label = match field_attrs.rename { - Some(value) => Some(Ident::new(&value.replace("\"", ""), field.span())), - None => field.ident.clone(), - }; - let field_label_name = renamed_field_label.unwrap().to_string(); + let field_label_name = Field::renamed_label(field, root_attributes); - match get_field_type(field) { - Some(FieldType::FieldTypeString) - | Some(FieldType::FieldTypeBool) - | Some(FieldType::FieldTypeU8) - | Some(FieldType::FieldTypeI8) - | Some(FieldType::FieldTypeU16) - | Some(FieldType::FieldTypeI16) - | Some(FieldType::FieldTypeU32) - | Some(FieldType::FieldTypeI32) - | Some(FieldType::FieldTypeF32) - | Some(FieldType::FieldTypeU64) - | Some(FieldType::FieldTypeI64) - | Some(FieldType::FieldTypeF64) => Some({ + match Field::from(field) { + Field::FieldString + | Field::FieldBool + | Field::FieldU8 + | Field::FieldI8 + | Field::FieldU16 + | Field::FieldI16 + | Field::FieldU32 + | Field::FieldI32 + | Field::FieldF32 + | Field::FieldU64 + | Field::FieldI64 + | Field::FieldF64 => Some({ quote! { match self { &#name::#label{ref #field_label, ..} => { @@ -101,7 +95,7 @@ fn inner_enum_inspector( } } }), - Some(FieldType::FieldTypeStruct { .. }) => Some(quote! { + Field::FieldStruct { .. } => Some(quote! { match self { &#name::#label{ref #field_label, ..} => { writer.set_start_event_name(Some(#field_label_name.to_string())); @@ -111,7 +105,7 @@ fn inner_enum_inspector( _ => {} } }), - Some(FieldType::FieldTypeVec { .. }) => Some(quote! { + Field::FieldVec { .. } => Some(quote! { match self { &#name::#label{ref #field_label, ..} => { for item in #field_label { @@ -123,7 +117,7 @@ fn inner_enum_inspector( _ => {} } }), - _ => None, + Field::FieldOption { .. } => None, } }) .filter_map(|x| x) @@ -139,9 +133,8 @@ fn inner_enum_inspector( let enum_fields: TokenStream = fields .unnamed .iter() - .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - if field_attrs.attribute { + .map(|token_field| { + if Field::is_attribute(token_field) { return None; } @@ -176,7 +169,7 @@ fn inner_enum_inspector( let write_sub_type = |data_type| { write_element(match data_type { - FieldType::FieldTypeString => &write_string_chars, + Field::FieldString => &write_string_chars, _ => &serialize, }) }; @@ -192,8 +185,8 @@ fn inner_enum_inspector( } }; - match get_field_type(field) { - Some(FieldType::FieldTypeOption { data_type }) => { + match Field::from(token_field) { + Field::FieldOption { data_type } => { let write = write_sub_type(*data_type); Some(match_field("e! { @@ -202,7 +195,7 @@ fn inner_enum_inspector( } })) } - Some(FieldType::FieldTypeVec { data_type }) => { + Field::FieldVec { data_type } => { let write = write_sub_type(*data_type); Some(match_field("e! { @@ -211,14 +204,9 @@ fn inner_enum_inspector( } })) } - Some(FieldType::FieldTypeStruct { .. }) => { - Some(write_element(&match_field(&serialize))) - } - Some(FieldType::FieldTypeString) => { - Some(match_field(&write_element(&write_string_chars))) - } - Some(_simple_type) => Some(match_field(&write_simple_type)), - _ => None, + Field::FieldStruct { .. } => Some(write_element(&match_field(&serialize))), + Field::FieldString => Some(match_field(&write_element(&write_string_chars))), + _simple_type => Some(match_field(&write_simple_type)), } }) .filter_map(|x| x) diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 16bfed5..32567f9 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -1,8 +1,6 @@ -use crate::attribute::*; -use crate::field_type::*; -use crate::ser::{ - element::*, implement_deserializer::implement_deserializer, label::build_label_name, -}; +use crate::common::{Field, YaSerdeAttribute}; + +use crate::ser::{element::*, implement_deserializer::implement_deserializer}; use proc_macro2::TokenStream; use syn::spanned::Spanned; use syn::DataStruct; @@ -19,31 +17,26 @@ pub fn serialize( .iter() .map(|field| { let field_attrs = YaSerdeAttribute::parse(&field.attrs); - if !field_attrs.attribute { + if !Field::is_attribute(field) { return None; } - let label = &field.ident; + let label = Field::label(field); + let label_name = Field::renamed_label(field, root_attributes); - let label_name = build_label_name( - &label.as_ref().unwrap(), - &field_attrs, - &root_attributes.default_namespace, - ); - - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeString - | FieldType::FieldTypeBool - | FieldType::FieldTypeI8 - | FieldType::FieldTypeU8 - | FieldType::FieldTypeI16 - | FieldType::FieldTypeU16 - | FieldType::FieldTypeI32 - | FieldType::FieldTypeU32 - | FieldType::FieldTypeI64 - | FieldType::FieldTypeU64 - | FieldType::FieldTypeF32 - | FieldType::FieldTypeF64 => { + match Field::from(field) { + Field::FieldString + | Field::FieldBool + | Field::FieldI8 + | Field::FieldU8 + | Field::FieldI16 + | Field::FieldU16 + | Field::FieldI32 + | Field::FieldU32 + | Field::FieldI64 + | Field::FieldU64 + | Field::FieldF32 + | Field::FieldF64 => { if let Some(ref d) = field_attrs.default { let default_function = Ident::new(&d, field.span()); Some(quote! { @@ -62,8 +55,8 @@ pub fn serialize( }) } } - FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeString => { + Field::FieldOption { data_type } => match *data_type { + Field::FieldString => { if let Some(ref d) = field_attrs.default { let default_function = Ident::new(&d, field.span()); Some(quote! { @@ -89,17 +82,17 @@ pub fn serialize( }) } } - FieldType::FieldTypeBool - | FieldType::FieldTypeI8 - | FieldType::FieldTypeU8 - | FieldType::FieldTypeI16 - | FieldType::FieldTypeU16 - | FieldType::FieldTypeI32 - | FieldType::FieldTypeU32 - | FieldType::FieldTypeI64 - | FieldType::FieldTypeU64 - | FieldType::FieldTypeF32 - | FieldType::FieldTypeF64 => { + Field::FieldBool + | Field::FieldI8 + | Field::FieldU8 + | Field::FieldI16 + | Field::FieldU16 + | Field::FieldI32 + | Field::FieldU32 + | Field::FieldI64 + | Field::FieldU64 + | Field::FieldF32 + | Field::FieldF64 => { if let Some(ref d) = field_attrs.default { let default_function = Ident::new(&d, field.span()); Some(quote! { @@ -127,7 +120,7 @@ pub fn serialize( }) } } - FieldType::FieldTypeVec { .. } => { + Field::FieldVec { .. } => { let item_ident = Ident::new("yaserde_item", field.span()); let inner = enclose_formatted_characters(&item_ident, label_name); @@ -151,7 +144,7 @@ pub fn serialize( }) } } - FieldType::FieldTypeStruct { .. } => { + Field::FieldStruct { .. } => { if let Some(ref d) = field_attrs.default { let default_function = Ident::new(&d, field.span()); Some(quote! { @@ -183,7 +176,7 @@ pub fn serialize( } _ => unimplemented!(), }, - FieldType::FieldTypeStruct { .. } => { + Field::FieldStruct { .. } => { if let Some(ref d) = field_attrs.default { let default_function = Ident::new(&d, field.span()); Some(quote! { @@ -203,7 +196,7 @@ pub fn serialize( } } _ => None, - }) + } }) .filter_map(|x| x) .collect(); @@ -213,51 +206,49 @@ pub fn serialize( .iter() .map(|field| { let field_attrs = YaSerdeAttribute::parse(&field.attrs); - if field_attrs.attribute { + if Field::is_attribute(field) { return None; } - let label = &field.ident; - if field_attrs.text { + let label = Field::label(field); + if Field::is_text_content(field) { return Some(quote!( let data_event = XmlEvent::characters(&self.#label); writer.write(data_event).map_err(|e| e.to_string())?; )); } - let label_name = build_label_name( - &label.as_ref().unwrap(), - &field_attrs, - &root_attributes.default_namespace, - ); - let conditions = condition_generator(label, &field_attrs); + let label_name = Field::renamed_label(field, root_attributes); - get_field_type(field).and_then(|f| match f { - FieldType::FieldTypeString - | FieldType::FieldTypeBool - | FieldType::FieldTypeI8 - | FieldType::FieldTypeU8 - | FieldType::FieldTypeI16 - | FieldType::FieldTypeU16 - | FieldType::FieldTypeI32 - | FieldType::FieldTypeU32 - | FieldType::FieldTypeI64 - | FieldType::FieldTypeU64 - | FieldType::FieldTypeF32 - | FieldType::FieldTypeF64 => serialize_element(label, label_name, &conditions), - FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeString - | FieldType::FieldTypeBool - | FieldType::FieldTypeI8 - | FieldType::FieldTypeU8 - | FieldType::FieldTypeI16 - | FieldType::FieldTypeU16 - | FieldType::FieldTypeI32 - | FieldType::FieldTypeU32 - | FieldType::FieldTypeI64 - | FieldType::FieldTypeU64 - | FieldType::FieldTypeF32 - | FieldType::FieldTypeF64 => { + let conditions = condition_generator(&label, &field_attrs); + + match Field::from(field) { + Field::FieldString + | Field::FieldBool + | Field::FieldI8 + | Field::FieldU8 + | Field::FieldI16 + | Field::FieldU16 + | Field::FieldI32 + | Field::FieldU32 + | Field::FieldI64 + | Field::FieldU64 + | Field::FieldF32 + | Field::FieldF64 => serialize_element(&label, label_name, &conditions), + + Field::FieldOption { data_type } => match *data_type { + Field::FieldString + | Field::FieldBool + | Field::FieldI8 + | Field::FieldU8 + | Field::FieldI16 + | Field::FieldU16 + | Field::FieldI32 + | Field::FieldU32 + | Field::FieldI64 + | Field::FieldU64 + | Field::FieldF32 + | Field::FieldF64 => { let item_ident = Ident::new("yaserde_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); @@ -269,7 +260,7 @@ pub fn serialize( } }) } - FieldType::FieldTypeVec { .. } => { + Field::FieldVec { .. } => { let item_ident = Ident::new("yaserde_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); @@ -283,7 +274,7 @@ pub fn serialize( } }) } - FieldType::FieldTypeStruct { .. } => Some(if field_attrs.flatten { + Field::FieldStruct { .. } => Some(if field_attrs.flatten { quote! { if let Some(ref item) = &self.#label { writer.set_start_event_name(None); @@ -302,7 +293,7 @@ pub fn serialize( }), _ => unimplemented!(), }, - FieldType::FieldTypeStruct { .. } => { + Field::FieldStruct { .. } => { let (start_event, skip_start) = if field_attrs.flatten { (quote!(None), true) } else { @@ -315,8 +306,8 @@ pub fn serialize( self.#label.serialize(writer)?; }) } - FieldType::FieldTypeVec { data_type } => match *data_type { - FieldType::FieldTypeString => { + Field::FieldVec { data_type } => match *data_type { + Field::FieldString => { let item_ident = Ident::new("yaserde_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); @@ -326,17 +317,17 @@ pub fn serialize( } }) } - FieldType::FieldTypeBool - | FieldType::FieldTypeI8 - | FieldType::FieldTypeU8 - | FieldType::FieldTypeI16 - | FieldType::FieldTypeU16 - | FieldType::FieldTypeI32 - | FieldType::FieldTypeU32 - | FieldType::FieldTypeI64 - | FieldType::FieldTypeU64 - | FieldType::FieldTypeF32 - | FieldType::FieldTypeF64 => { + Field::FieldBool + | Field::FieldI8 + | Field::FieldU8 + | Field::FieldI16 + | Field::FieldU16 + | Field::FieldI32 + | Field::FieldU32 + | Field::FieldI64 + | Field::FieldU64 + | Field::FieldF32 + | Field::FieldF64 => { let item_ident = Ident::new("yaserde_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); @@ -346,7 +337,7 @@ pub fn serialize( } }) } - FieldType::FieldTypeOption { .. } => Some(quote! { + Field::FieldOption { .. } => Some(quote! { for item in &self.#label { if let Some(value) = item { writer.set_start_event_name(None); @@ -355,18 +346,18 @@ pub fn serialize( } } }), - FieldType::FieldTypeStruct { .. } => Some(quote! { + Field::FieldStruct { .. } => Some(quote! { for item in &self.#label { writer.set_start_event_name(None); writer.set_skip_start_end(false); item.serialize(writer)?; } }), - FieldType::FieldTypeVec { .. } => { + Field::FieldVec { .. } => { unimplemented!(); } }, - }) + } }) .filter_map(|x| x) .collect(); diff --git a/yaserde_derive/src/ser/implement_deserializer.rs b/yaserde_derive/src/ser/implement_deserializer.rs index b128d7b..645b4ed 100644 --- a/yaserde_derive/src/ser/implement_deserializer.rs +++ b/yaserde_derive/src/ser/implement_deserializer.rs @@ -1,4 +1,4 @@ -use crate::attribute::YaSerdeAttribute; +use crate::common::YaSerdeAttribute; use crate::ser::namespace::generate_namespaces_definition; use proc_macro2::Ident; use proc_macro2::TokenStream; diff --git a/yaserde_derive/src/ser/label.rs b/yaserde_derive/src/ser/label.rs index b77ee2e..89998a5 100644 --- a/yaserde_derive/src/ser/label.rs +++ b/yaserde_derive/src/ser/label.rs @@ -1,4 +1,4 @@ -use crate::attribute::YaSerdeAttribute; +use crate::common::YaSerdeAttribute; use proc_macro2::Ident; pub fn build_label_name( diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs index 6e5e8c1..c294514 100644 --- a/yaserde_derive/src/ser/mod.rs +++ b/yaserde_derive/src/ser/mod.rs @@ -5,7 +5,7 @@ pub mod implement_deserializer; pub mod label; pub mod namespace; -use crate::attribute::YaSerdeAttribute; +use crate::common::YaSerdeAttribute; use proc_macro2::TokenStream; use syn; use syn::Ident; diff --git a/yaserde_derive/src/ser/namespace.rs b/yaserde_derive/src/ser/namespace.rs index 6a7bf5a..3127531 100644 --- a/yaserde_derive/src/ser/namespace.rs +++ b/yaserde_derive/src/ser/namespace.rs @@ -1,4 +1,4 @@ -use crate::attribute::YaSerdeAttribute; +use crate::common::YaSerdeAttribute; use proc_macro2::TokenStream; pub fn generate_namespaces_definition(attributes: &YaSerdeAttribute) -> TokenStream { From f69d5e75b3021805353cda6e64bc800905e895a6 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Tue, 21 Apr 2020 18:01:03 +0200 Subject: [PATCH 4/7] implement common default skip content serializer --- yaserde_derive/src/common/field.rs | 90 ++++++++++++ yaserde_derive/src/common/mod.rs | 2 +- yaserde_derive/src/ser/expand_enum.rs | 15 +- yaserde_derive/src/ser/expand_struct.rs | 184 +++++++----------------- 4 files changed, 150 insertions(+), 141 deletions(-) diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index 6e01569..4d0e2a4 100644 --- a/yaserde_derive/src/common/field.rs +++ b/yaserde_derive/src/common/field.rs @@ -1,8 +1,98 @@ use crate::common::attribute::YaSerdeAttribute; use proc_macro2::{Ident, TokenStream}; +use proc_macro2::Span; use std::fmt; use syn; use syn::Type::Path; +use syn::spanned::Spanned; + +#[derive(Debug)] +pub struct YaSerdeField { + syn_field: syn::Field, + attributes: YaSerdeAttribute, +} + +impl YaSerdeField { + pub fn new(syn_field: syn::Field) -> Self { + let attributes = YaSerdeAttribute::parse(&syn_field.attrs); + + YaSerdeField{ + syn_field, + attributes, + } + } + + pub fn is_attribute(&self) -> bool { + self.attributes.attribute + } + + pub fn is_text_content(&self) -> bool { + self.attributes.text + } + + pub fn label(&self) -> Option { + self.syn_field.ident.clone() + } + + pub fn renamed_label(&self, root_attributes: &YaSerdeAttribute) -> String { + let prefix = if root_attributes.default_namespace == self.attributes.prefix { + "".to_string() + } else { + self.attributes + .prefix + .clone() + .map_or("".to_string(), |prefix| prefix + ":") + }; + + let label = + self.attributes + .rename + .clone() + .unwrap_or_else(|| self.label().as_ref().unwrap().to_string()); + + format!("{}{}", prefix, label) + } + + pub fn get_type(&self) -> Field { + Field::from(&self.syn_field) + } + + pub fn get_span(&self) -> Span { + self.syn_field.span() + } + + pub fn get_default_function(&self) -> Option { + self.attributes.default.as_ref().map(|default|{ + Ident::new(&default, self.get_span()) + }) + } + + pub fn get_skip_serializing_if_function(&self) -> Option { + self.attributes.skip_serializing_if.as_ref().map(|skip_serializing_if|{ + Ident::new(&skip_serializing_if, self.get_span()) + }) + } + + pub fn ser_wrap_default_attribute(&self, builder: TokenStream, setter: TokenStream) -> TokenStream { + let label = self.label(); + if let Some(ref default_function) = self.get_default_function() { + quote! { + let yaserde_inner = #builder; + let struct_start_event = + if self.#label != #default_function() { + #setter + } else { + struct_start_event + }; + } + } else { + quote! { + let yaserde_inner = #builder; + let struct_start_event = #setter; + } + } + } +} #[derive(Debug)] pub enum Field { diff --git a/yaserde_derive/src/common/mod.rs b/yaserde_derive/src/common/mod.rs index 2dc2de9..cee0625 100644 --- a/yaserde_derive/src/common/mod.rs +++ b/yaserde_derive/src/common/mod.rs @@ -2,4 +2,4 @@ mod attribute; mod field; pub use attribute::YaSerdeAttribute; -pub use field::Field; +pub use field::{Field, YaSerdeField}; diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index cb85a93..74a04bf 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -1,4 +1,4 @@ -use crate::common::{Field, YaSerdeAttribute}; +use crate::common::{Field, YaSerdeAttribute, YaSerdeField}; use crate::ser::{implement_deserializer::implement_deserializer, label::build_label_name}; use proc_macro2::TokenStream; use syn::DataEnum; @@ -49,23 +49,22 @@ fn inner_enum_inspector( let enum_fields: TokenStream = fields .named .iter() + .map(|field| YaSerdeField::new(field.clone())) + .filter(|field| !field.is_attribute()) .map(|field| { - if Field::is_attribute(field) { - return None; - } - let field_label = Field::label(field); + let field_label = field.label(); - if Field::is_text_content(field) { + if field.is_text_content() { return Some(quote!( let data_event = XmlEvent::characters(&self.#field_label); writer.write(data_event).map_err(|e| e.to_string())?; )); } - let field_label_name = Field::renamed_label(field, root_attributes); + let field_label_name = field.renamed_label(root_attributes); - match Field::from(field) { + match field.get_type() { Field::FieldString | Field::FieldBool | Field::FieldU8 diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 32567f9..c37b5e7 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -1,4 +1,4 @@ -use crate::common::{Field, YaSerdeAttribute}; +use crate::common::{Field, YaSerdeAttribute, YaSerdeField}; use crate::ser::{element::*, implement_deserializer::implement_deserializer}; use proc_macro2::TokenStream; @@ -15,16 +15,13 @@ pub fn serialize( let build_attributes: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) + .filter(|field| field.is_attribute()) .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - if !Field::is_attribute(field) { - return None; - } + let label = field.label(); + let label_name = field.renamed_label(root_attributes); - let label = Field::label(field); - let label_name = Field::renamed_label(field, root_attributes); - - match Field::from(field) { + match field.get_type() { Field::FieldString | Field::FieldBool | Field::FieldI8 @@ -37,50 +34,25 @@ pub fn serialize( | Field::FieldU64 | Field::FieldF32 | Field::FieldF64 => { - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, field.span()); - Some(quote! { - let content = self.#label.to_string(); - let struct_start_event = - if self.#label != #default_function() { - struct_start_event.attr(#label_name, &content) - } else { - struct_start_event - }; + Some(field.ser_wrap_default_attribute( + quote!(self.#label.to_string()), + quote!({ + struct_start_event.attr(#label_name, &yaserde_inner) }) - } else { - Some(quote! { - let content = self.#label.to_string(); - let struct_start_event = struct_start_event.attr(#label_name, &content); - }) - } + )) } Field::FieldOption { data_type } => match *data_type { Field::FieldString => { - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, field.span()); - 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 - }; + Some(field.ser_wrap_default_attribute( + quote!({}), + quote!({ + if let Some(ref value) = self.#label { + struct_start_event.attr(#label_name, value) + } else { + struct_start_event + } }) - } else { - Some(quote! { - let struct_start_event = - if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, &value) - } else { - struct_start_event - }; - }) - } + )) } Field::FieldBool | Field::FieldI8 @@ -93,109 +65,57 @@ pub fn serialize( | Field::FieldU64 | Field::FieldF32 | Field::FieldF64 => { - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, field.span()); - Some(quote! { - let content = self.#label.map_or_else(|| String::new(), |v| v.to_string()); - let struct_start_event = - if self.#label != #default_function() { - if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, &content) - } else { - struct_start_event - } - } else { - struct_start_event - }; + Some(field.ser_wrap_default_attribute( + quote!(self.#label.map_or_else(|| String::new(), |v| v.to_string())), + quote!({ + if let Some(ref value) = self.#label { + struct_start_event.attr(#label_name, &yaserde_inner) + } else { + struct_start_event + } }) - } else { - Some(quote! { - let content = self.#label.map_or_else(|| String::new(), |v| v.to_string()); - let struct_start_event = - if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, &content) - } else { - struct_start_event - }; - }) - } + )) } Field::FieldVec { .. } => { - let item_ident = Ident::new("yaserde_item", field.span()); + let item_ident = Ident::new("yaserde_item", field.get_span()); let inner = enclose_formatted_characters(&item_ident, label_name); - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, field.span()); - - Some(quote! { - if self.#label != #default_function() { - if let Some(ref yaserde_list) = self.#label { - for yaserde_item in yaserde_list.iter() { - #inner - } + Some(field.ser_wrap_default_attribute( + quote!({}), + quote!({ + if let Some(ref yaserde_list) = self.#label { + for yaserde_item in yaserde_list.iter() { + #inner } } }) - } else { - Some(quote! { - for yaserde_item in &self.#label { - #inner - } - }) - } + )) } Field::FieldStruct { .. } => { - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, field.span()); - Some(quote! { - let content = self.#label + Some(field.ser_wrap_default_attribute( + quote!(self.#label .as_ref() - .map_or_else(|| Ok(String::new()), |v| yaserde::ser::to_string_content(v))?; - let struct_start_event = if let Some(ref value) = self.#label { - if *value != #default_function() { - struct_start_event.attr(#label_name, &content) - } else { - struct_start_event - } + .map_or_else(|| Ok(String::new()), |v| yaserde::ser::to_string_content(v))?), + quote!({ + if let Some(ref yaserde_struct) = self.#label { + struct_start_event.attr(#label_name, &yaserde_inner) } else { struct_start_event - }; + } }) - } else { - Some(quote! { - let content = self.#label - .as_ref() - .map_or_else(|| Ok(String::new()), |v| yaserde::ser::to_string_content(v))?; - let struct_start_event = if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, &content) - } else { - struct_start_event - }; - }) - } + )) } - _ => unimplemented!(), + Field::FieldOption { .. } => unimplemented!(), }, Field::FieldStruct { .. } => { - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, field.span()); - Some(quote! { - let content = yaserde::ser::to_string_content(&self.#label)?; - let struct_start_event = - if self.#label != #default_function() { - struct_start_event.attr(#label_name, &content) - } else { - struct_start_event - }; + Some(field.ser_wrap_default_attribute( + quote!(yaserde::ser::to_string_content(&self.#label)?), + quote!({ + struct_start_event.attr(#label_name, &yaserde_inner) }) - } else { - Some(quote! { - let content = yaserde::ser::to_string_content(&self.#label)?; - let struct_start_event = struct_start_event.attr(#label_name, &content); - }) - } + )) } - _ => None, + Field::FieldVec { .. } => None, } }) .filter_map(|x| x) From 0872461c41f17f1690b079207b7097495158cfbd Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Wed, 22 Apr 2020 18:18:11 +0200 Subject: [PATCH 5/7] continue to refactor code using common Field structure --- yaserde/tests/option.rs | 1 + yaserde/tests/skip_if.rs | 10 + yaserde_derive/src/common/field.rs | 133 +++++++++--- yaserde_derive/src/de/build_default_value.rs | 32 ++- yaserde_derive/src/de/expand_enum.rs | 19 +- yaserde_derive/src/de/expand_struct.rs | 210 ++++++------------- yaserde_derive/src/ser/element.rs | 53 ++--- yaserde_derive/src/ser/expand_enum.rs | 11 +- yaserde_derive/src/ser/expand_struct.rs | 131 +++++------- 9 files changed, 280 insertions(+), 320 deletions(-) diff --git a/yaserde/tests/option.rs b/yaserde/tests/option.rs index 9609796..cc9a4bd 100644 --- a/yaserde/tests/option.rs +++ b/yaserde/tests/option.rs @@ -37,6 +37,7 @@ fn basic_option_types() { test_for_type!(Option::, Some(-12.5 as f64), Some("-12.5")); test_for_type!(Option::, None, None); + // TODO // test_for_type!(Option::>, None, None); // test_for_type!(Option::>, Some(vec![0]), Some("0")); // test_for_type!(Option::>, None, None); diff --git a/yaserde/tests/skip_if.rs b/yaserde/tests/skip_if.rs index ad6f9de..ed45cb2 100644 --- a/yaserde/tests/skip_if.rs +++ b/yaserde/tests/skip_if.rs @@ -8,9 +8,18 @@ use yaserde::YaSerialize; #[test] fn skip_serializing_if_for_struct() { + fn default_string_function() -> String { + "mask_default".to_string() + } + #[derive(YaSerialize, PartialEq, Debug)] #[yaserde(root = "base")] pub struct XmlStruct { + #[yaserde( + skip_serializing_if = "check_string_function", + default = "default_string_function" + )] + string_with_default_item: String, #[yaserde(skip_serializing_if = "check_string_function")] string_item: String, #[yaserde(skip_serializing_if = "check_bool_function")] @@ -40,6 +49,7 @@ fn skip_serializing_if_for_struct() { } let model = XmlStruct { + string_with_default_item: "mask_default".to_string(), string_item: "something".to_string(), bool_item: true, f32_item: 0.0, diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index 4d0e2a4..e2faa0a 100644 --- a/yaserde_derive/src/common/field.rs +++ b/yaserde_derive/src/common/field.rs @@ -1,10 +1,10 @@ use crate::common::attribute::YaSerdeAttribute; -use proc_macro2::{Ident, TokenStream}; use proc_macro2::Span; +use proc_macro2::{Ident, TokenStream}; use std::fmt; use syn; -use syn::Type::Path; use syn::spanned::Spanned; +use syn::Type::Path; #[derive(Debug)] pub struct YaSerdeField { @@ -16,7 +16,7 @@ impl YaSerdeField { pub fn new(syn_field: syn::Field) -> Self { let attributes = YaSerdeAttribute::parse(&syn_field.attrs); - YaSerdeField{ + YaSerdeField { syn_field, attributes, } @@ -30,29 +30,70 @@ impl YaSerdeField { self.attributes.text } + pub fn is_flatten(&self) -> bool { + self.attributes.flatten + } + + // pub fn get_attributes(&self) -> YaSerdeAttribute { + // self.attributes.clone() + // } + pub fn label(&self) -> Option { self.syn_field.ident.clone() } + pub fn get_value_label(&self) -> Option { + self + .syn_field + .ident + .clone() + .map(|ident| syn::Ident::new(&format!("__{}_value", ident.to_string()), ident.span())) + } + + pub fn renamed_label_without_namespace(&self) -> String { + self + .attributes + .rename + .clone() + .unwrap_or_else(|| self.label().as_ref().unwrap().to_string()) + } + pub fn renamed_label(&self, root_attributes: &YaSerdeAttribute) -> String { let prefix = if root_attributes.default_namespace == self.attributes.prefix { "".to_string() } else { - self.attributes + self + .attributes .prefix .clone() .map_or("".to_string(), |prefix| prefix + ":") }; - let label = - self.attributes - .rename - .clone() - .unwrap_or_else(|| self.label().as_ref().unwrap().to_string()); + let label = self.renamed_label_without_namespace(); format!("{}{}", prefix, label) } + pub fn get_visitor_ident(&self, struct_name: Option<&syn::Path>) -> Ident { + let label = self.renamed_label_without_namespace(); + + let struct_id = struct_name.map_or_else( + || "".to_string(), + |struct_name| { + struct_name + .segments + .iter() + .map(|s| s.ident.to_string()) + .collect() + }, + ); + + Ident::new( + &format!("__Visitor_{}_{}", label.replace(".", "_"), struct_id), + self.get_span(), + ) + } + pub fn get_type(&self) -> Field { Field::from(&self.syn_field) } @@ -62,35 +103,64 @@ impl YaSerdeField { } pub fn get_default_function(&self) -> Option { - self.attributes.default.as_ref().map(|default|{ - Ident::new(&default, self.get_span()) - }) + self + .attributes + .default + .as_ref() + .map(|default| Ident::new(&default, self.get_span())) } pub fn get_skip_serializing_if_function(&self) -> Option { - self.attributes.skip_serializing_if.as_ref().map(|skip_serializing_if|{ - Ident::new(&skip_serializing_if, self.get_span()) - }) + self + .attributes + .skip_serializing_if + .as_ref() + .map(|skip_serializing_if| Ident::new(&skip_serializing_if, self.get_span())) } - pub fn ser_wrap_default_attribute(&self, builder: TokenStream, setter: TokenStream) -> TokenStream { + pub fn get_namespace_matching(&self, root_attributes: &YaSerdeAttribute) -> TokenStream { + root_attributes + .namespaces + .iter() + .map(|(prefix, namespace)| { + if self.attributes.prefix == Some(prefix.to_string()) { + Some(quote!(#namespace => {})) + } else { + None + } + }) + .filter_map(|x| x) + .collect() + } + + pub fn ser_wrap_default_attribute( + &self, + builder: Option, + setter: TokenStream, + ) -> TokenStream { let label = self.label(); - if let Some(ref default_function) = self.get_default_function() { - quote! { - let yaserde_inner = #builder; - let struct_start_event = - if self.#label != #default_function() { - #setter - } else { - struct_start_event - }; - } - } else { - quote! { - let yaserde_inner = #builder; + + let yaserde_inner_definition = builder + .map(|builder| quote!(let yaserde_inner = #builder;)) + .unwrap_or(quote!()); + + self + .get_default_function() + .map(|default_function| { + quote! { + #yaserde_inner_definition + let struct_start_event = + if self.#label != #default_function() { + #setter + } else { + struct_start_event + }; + } + }) + .unwrap_or(quote! { + #yaserde_inner_definition let struct_start_event = #setter; - } - } + }) } } @@ -140,7 +210,6 @@ impl Field { let label = attributes .rename - .clone() .unwrap_or_else(|| token_field.ident.as_ref().unwrap().to_string()); format!("{}{}", prefix, label) diff --git a/yaserde_derive/src/de/build_default_value.rs b/yaserde_derive/src/de/build_default_value.rs index 22a024e..cd1484d 100644 --- a/yaserde_derive/src/de/build_default_value.rs +++ b/yaserde_derive/src/de/build_default_value.rs @@ -1,28 +1,24 @@ -use proc_macro2::{Span, TokenStream}; -use syn::Ident; +use crate::common::YaSerdeField; +use proc_macro2::TokenStream; pub fn build_default_value( - label: &Option, - field_type: &TokenStream, - value: &TokenStream, - default: &Option, + field: &YaSerdeField, + field_type: Option, + value: TokenStream, ) -> Option { - let value = default - .as_ref() - .map(|d| { - let default_function = Ident::new( - &d, - label - .as_ref() - .map_or(Span::call_site(), |ident| ident.span()), - ); + let label = field.get_value_label(); - quote!(#default_function()) - }) + let default_value = field + .get_default_function() + .map(|default_function| quote!(#default_function())) .unwrap_or_else(|| quote!(#value)); + let field_type = field_type + .map(|field_type| quote!(: #field_type)) + .unwrap_or(quote!()); + Some(quote! { #[allow(unused_mut)] - let mut #label : #field_type = #value; + let mut #label #field_type = #default_value; }) } diff --git a/yaserde_derive/src/de/expand_enum.rs b/yaserde_derive/src/de/expand_enum.rs index c1efe82..76a110d 100644 --- a/yaserde_derive/src/de/expand_enum.rs +++ b/yaserde_derive/src/de/expand_enum.rs @@ -1,11 +1,6 @@ -use crate::common::{Field, YaSerdeAttribute}; +use crate::common::{Field, YaSerdeAttribute, YaSerdeField}; use proc_macro2::TokenStream; -use syn::{ - spanned::Spanned, - DataEnum, - Fields, - Ident, -}; +use syn::{DataEnum, Fields, Ident}; pub fn parse( data_enum: &DataEnum, @@ -142,9 +137,10 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { fields .unnamed .iter() + .map(|field| YaSerdeField::new(field.clone())) .enumerate() .map(|(idx, field)| { - let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span()); + let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.get_span()); let make_visitor = |visitor: &TokenStream, field_type: &TokenStream, fn_body: &TokenStream| { @@ -172,7 +168,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { ) }; - match Field::from(field) { + match field.get_type() { Field::FieldStruct { struct_name } => { let struct_id: String = struct_name .segments @@ -208,9 +204,10 @@ fn build_unnamed_visitor_calls( fields .unnamed .iter() + .map(|field| YaSerdeField::new(field.clone())) .enumerate() .map(|(idx, field)| { - let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span()); + let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.get_span()); let call_simple_type_visitor = |simple_type: Field, action| { let visitor = simple_type.get_simple_type_visitor(); @@ -278,7 +275,7 @@ fn build_unnamed_visitor_calls( } }; - match Field::from(field) { + match field.get_type() { Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_val), Field::FieldOption { data_type } => match *data_type { Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_opt), diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 4066e62..0bc283f 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -1,12 +1,7 @@ -use crate::common::{Field, YaSerdeAttribute}; +use crate::common::{Field, YaSerdeAttribute, YaSerdeField}; use crate::de::build_default_value::build_default_value; use proc_macro2::{Span, TokenStream}; -use std::collections::BTreeMap; -use syn::{ - spanned::Spanned, - DataStruct, - Ident, -}; +use syn::{DataStruct, Ident}; pub fn parse( data_struct: &DataStruct, @@ -17,9 +12,9 @@ pub fn parse( let namespaces_matches: TokenStream = root_attributes .namespaces .iter() - .map(|(p, ns)| { - if root_attributes.prefix.as_ref() == Some(p) { - Some(quote!(#ns => {})) + .map(|(prefix, namespace)| { + if root_attributes.prefix.as_ref() == Some(prefix) { + Some(quote!(#namespace => {})) } else { None } @@ -30,63 +25,32 @@ pub fn parse( let variables: TokenStream = data_struct .fields .iter() - .map(|field| { - let label = &get_value_label(&field.ident); - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - - match Field::from(field) { - Field::FieldStruct { struct_name } => build_default_value( - label, - "e! {#struct_name}, - "e! {#struct_name::default()}, - &field_attrs.default, - ), - Field::FieldOption { .. } => { - if let Some(d) = &field_attrs.default { - let default_function = Ident::new(&d, field.span()); - - Some(quote! { - #[allow(unused_mut, non_snake_case, non_camel_case_types)] - let mut #label = #default_function(); - }) - } else { - Some(quote! { - #[allow(unused_mut, non_snake_case, non_camel_case_types)] - let mut #label = None; - }) - } + .map(|field| YaSerdeField::new(field.clone())) + .map(|field| match field.get_type() { + Field::FieldStruct { struct_name } => build_default_value( + &field, + Some(quote!(#struct_name)), + quote!(#struct_name::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 { .. } | Field::FieldVec { .. } => { + unimplemented!(); } - Field::FieldVec { data_type } => match *data_type { - Field::FieldStruct { ref struct_name } => build_default_value( - label, - "e! {Vec<#struct_name>}, - "e! {vec![]}, - &field_attrs.default, - ), - Field::FieldOption { .. } | Field::FieldVec { .. } => { - unimplemented!(); - } - simple_type => { - let type_token: TokenStream = simple_type.into(); - - build_default_value( - label, - "e! {Vec<#type_token>}, - "e! {vec![]}, - &field_attrs.default, - ) - } - }, simple_type => { let type_token: TokenStream = simple_type.into(); - build_default_value( - label, - &type_token, - "e! {#type_token::default()}, - &field_attrs.default, - ) + build_default_value(&field, Some(quote!(Vec<#type_token>)), quote!(vec![])) } + }, + simple_type => { + let type_token: TokenStream = simple_type.into(); + let value_builder = quote!(#type_token::default()); + + build_default_value(&field, Some(type_token), value_builder) } }) .filter_map(|x| x) @@ -95,12 +59,8 @@ pub fn parse( let field_visitors: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - let label_name = field_attrs - .rename - .unwrap_or_else(|| field.ident.as_ref().unwrap().to_string()); - let struct_visitor = |struct_name: syn::Path| { let struct_id: String = struct_name .segments @@ -108,7 +68,7 @@ pub fn parse( .map(|s| s.ident.to_string()) .collect(); - let visitor_label = build_visitor_ident(&label_name, field.span(), Some(&struct_name)); + let visitor_label = field.get_visitor_ident(Some(&struct_name)); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -127,7 +87,7 @@ pub fn parse( let simple_type_visitor = |simple_type: Field| { let visitor = simple_type.get_simple_type_visitor(); - let visitor_label = build_visitor_ident(&label_name, field.span(), None); + let visitor_label = field.get_visitor_ident(None); let field_type: TokenStream = simple_type.into(); Some(quote! { @@ -143,7 +103,7 @@ pub fn parse( }) }; - match Field::from(field) { + match field.get_type() { Field::FieldStruct { struct_name } => struct_visitor(struct_name), Field::FieldOption { data_type } => match *data_type { Field::FieldStruct { struct_name } => struct_visitor(struct_name), @@ -164,19 +124,11 @@ pub fn parse( let call_visitors: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) + .filter(|field| !field.is_attribute() || !field.is_flatten()) .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - let label = &field.ident; - let value_label = &get_value_label(&field.ident); - - if field_attrs.attribute || field_attrs.flatten { - return None; - } - - let label_name = field_attrs - .rename - .clone() - .unwrap_or_else(|| label.as_ref().unwrap().to_string()); + let value_label = field.get_value_label(); + let label_name = field.renamed_label_without_namespace(); let visit_struct = |struct_name: syn::Path, action: TokenStream| { Some(quote! { @@ -201,10 +153,8 @@ pub fn parse( &field_type, &field_visitor, &action, - &field_attrs, - label, - &root_attributes.namespaces, - field.span(), + &field, + &root_attributes, ) }; @@ -214,7 +164,7 @@ pub fn parse( simple_type => visit_simple(simple_type, action), }; - match Field::from(field) { + 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::FieldVec { data_type } => visit_sub(data_type, quote! {.push(value)}), @@ -227,15 +177,12 @@ pub fn parse( let call_flatten_visitors: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) + .filter(|field| !field.is_attribute() && field.is_flatten()) .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - let value_label = &get_value_label(&field.ident); + let value_label = field.get_value_label(); - if field_attrs.attribute || !field_attrs.flatten { - return None; - } - - match Field::from(field) { + match field.get_type() { Field::FieldStruct { .. } => Some(quote! { #value_label = yaserde::de::from_str(&unused_xml_elements)?; }), @@ -243,9 +190,9 @@ pub fn parse( Field::FieldStruct { .. } => Some(quote! { #value_label = yaserde::de::from_str(&unused_xml_elements).ok(); }), - field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type), + field_type => unimplemented!(r#""flatten" is not implemented for {:?}"#, field_type), }, - field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type), + field_type => unimplemented!(r#""flatten" is not implemented for {:?}"#, field_type), } }) .filter_map(|x| x) @@ -254,19 +201,12 @@ pub fn parse( let attributes_loading: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) + .filter(|field| field.is_attribute()) .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - if !field_attrs.attribute { - return None; - } - - let label = &get_value_label(&field.ident); - - let label_name = field_attrs - .rename - .unwrap_or_else(|| field.ident.as_ref().unwrap().to_string()); - - let visitor_label = build_visitor_ident(&label_name, field.span(), None); + let label = field.get_value_label(); + let label_name = field.renamed_label_without_namespace(); + let visitor_label = build_visitor_ident(&label_name, field.get_span(), None); let visit = |action: &TokenStream, visitor: &TokenStream, visitor_label: &Ident| { Some(quote! { @@ -294,7 +234,7 @@ pub fn parse( visit( &action, "e! {visit_str}, - &build_visitor_ident(&label_name, field.span(), Some(&struct_name)), + &build_visitor_ident(&label_name, field.get_span(), Some(&struct_name)), ) }; @@ -312,7 +252,7 @@ pub fn parse( simple_type => visit_simple(simple_type, action), }; - match Field::from(field) { + match field.get_type() { Field::FieldString => visit_string(), Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}), Field::FieldVec { .. } => unimplemented!(), @@ -326,19 +266,19 @@ pub fn parse( let set_text: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) .map(|field| { - let label = &get_value_label(&field.ident); - let field_attrs = YaSerdeAttribute::parse(&field.attrs); + let label = field.get_value_label(); let set_text = |action: &TokenStream| { - if field_attrs.text { + if field.is_text_content() { Some(quote! {#label = #action;}) } else { None } }; - match Field::from(field) { + match field.get_type() { Field::FieldString => set_text("e! {text_content.to_owned()}), Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None, simple_type => { @@ -353,9 +293,10 @@ pub fn parse( let struct_builder: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) .map(|field| { - let label = &field.ident; - let value_label = &get_value_label(&field.ident); + let label = &field.label(); + let value_label = field.get_value_label(); quote! { #label: #value_label, } }) @@ -471,33 +412,14 @@ fn build_call_visitor( field_type: &TokenStream, visitor: &TokenStream, action: &TokenStream, - field_attrs: &YaSerdeAttribute, - label: &Option, - namespaces: &BTreeMap, - span: Span, + field: &YaSerdeField, + root_attributes: &YaSerdeAttribute, ) -> Option { - let prefix = field_attrs.prefix.clone(); + let value_label = field.get_value_label(); + let label_name = field.renamed_label_without_namespace(); + let visitor_label = build_visitor_ident(&label_name, field.get_span(), None); - // let label = &field.ident; - let value_label = get_value_label(label); - let label_name = field_attrs - .rename - .clone() - .unwrap_or_else(|| label.as_ref().unwrap().to_string()); - - let visitor_label = build_visitor_ident(&label_name, span, None); - - let namespaces_matches: TokenStream = namespaces - .iter() - .map(|(p, ns)| { - if prefix == Some(p.to_string()) { - Some(quote!(#ns => {})) - } else { - None - } - }) - .filter_map(|x| x) - .collect(); + let namespaces_matches = field.get_namespace_matching(root_attributes); Some(quote! { #label_name => { @@ -530,12 +452,6 @@ fn build_call_visitor( }) } -fn get_value_label(ident: &Option) -> Option { - ident - .clone() - .map(|ident| syn::Ident::new(&format!("__{}_value", ident.to_string()), ident.span())) -} - fn build_visitor_ident(label: &str, span: Span, struct_name: Option<&syn::Path>) -> Ident { let struct_id = struct_name.map_or_else( || "".to_string(), diff --git a/yaserde_derive/src/ser/element.rs b/yaserde_derive/src/ser/element.rs index 65e5c44..d00e832 100644 --- a/yaserde_derive/src/ser/element.rs +++ b/yaserde_derive/src/ser/element.rs @@ -1,5 +1,5 @@ -use crate::common::YaSerdeAttribute; -use proc_macro2::{Ident, Span, TokenStream}; +use crate::common::YaSerdeField; +use proc_macro2::{Ident, TokenStream}; pub fn enclose_formatted_characters(label: &Ident, label_name: String) -> TokenStream { enclose_xml_event(label_name, quote!(format!("{}", &self.#label))) @@ -13,7 +13,7 @@ pub fn enclose_characters(label: &Option, label_name: String) -> TokenStr enclose_xml_event(label_name, quote!(format!("{}", self.#label))) } -pub fn enclose_xml_event(label_name: String, yaserde_format: TokenStream) -> TokenStream { +fn enclose_xml_event(label_name: String, yaserde_format: TokenStream) -> TokenStream { quote! { let start_event = XmlEvent::start_element(#label_name); writer.write(start_event).map_err(|e| e.to_string())?; @@ -41,34 +41,23 @@ pub fn serialize_element( }) } -pub fn condition_generator(label: &Option, attributes: &YaSerdeAttribute) -> TokenStream { - let mut conditions = None; +pub fn condition_generator(label: &Option, field: &YaSerdeField) -> TokenStream { + let default_condition = field + .get_default_function() + .map(|default_function| quote!(self.#label != #default_function())); - if let Some(ref d) = attributes.default { - let default_function = Ident::new( - &d, - label - .as_ref() - .map_or(Span::call_site(), |ident| ident.span()), - ); - - conditions = Some(quote!(self.#label != #default_function())) - } - - if let Some(ref s) = attributes.skip_serializing_if { - let skip_if_function = Ident::new( - &s, - label - .as_ref() - .map_or(Span::call_site(), |ident| ident.span()), - ); - - conditions = if let Some(prev_conditions) = conditions { - Some(quote!(!#skip_if_function() && #prev_conditions)) - } else { - Some(quote!(!self.#skip_if_function(&self.#label))) - }; - } - - conditions.map(|c| quote!(if #c)).unwrap_or(quote!()) + field + .get_skip_serializing_if_function() + .map(|skip_if_function| { + if let Some(prev_conditions) = &default_condition { + quote!(if !self.#skip_if_function(&self.#label) && #prev_conditions) + } else { + quote!(if !self.#skip_if_function(&self.#label)) + } + }) + .unwrap_or_else(|| { + default_condition + .map(|condition| quote!(if #condition)) + .unwrap_or(quote!()) + }) } diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index 74a04bf..eb9521c 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -52,7 +52,6 @@ fn inner_enum_inspector( .map(|field| YaSerdeField::new(field.clone())) .filter(|field| !field.is_attribute()) .map(|field| { - let field_label = field.label(); if field.is_text_content() { @@ -132,11 +131,9 @@ fn inner_enum_inspector( let enum_fields: TokenStream = fields .unnamed .iter() - .map(|token_field| { - if Field::is_attribute(token_field) { - return None; - } - + .map(|field| YaSerdeField::new(field.clone())) + .filter(|field| !field.is_attribute()) + .map(|field| { let write_element = |action: &TokenStream| { quote! { let struct_start_event = XmlEvent::start_element(#label_name); @@ -184,7 +181,7 @@ fn inner_enum_inspector( } }; - match Field::from(token_field) { + match field.get_type() { Field::FieldOption { data_type } => { let write = write_sub_type(*data_type); diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index c37b5e7..1201df4 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -2,7 +2,6 @@ use crate::common::{Field, YaSerdeAttribute, YaSerdeField}; use crate::ser::{element::*, implement_deserializer::implement_deserializer}; use proc_macro2::TokenStream; -use syn::spanned::Spanned; use syn::DataStruct; use syn::Ident; @@ -33,27 +32,23 @@ pub fn serialize( | Field::FieldI64 | Field::FieldU64 | Field::FieldF32 - | Field::FieldF64 => { - Some(field.ser_wrap_default_attribute( - quote!(self.#label.to_string()), - quote!({ - struct_start_event.attr(#label_name, &yaserde_inner) - }) - )) - } + | Field::FieldF64 => Some(field.ser_wrap_default_attribute( + Some(quote!(self.#label.to_string())), + quote!({ + struct_start_event.attr(#label_name, &yaserde_inner) + }), + )), Field::FieldOption { data_type } => match *data_type { - Field::FieldString => { - Some(field.ser_wrap_default_attribute( - quote!({}), - quote!({ - if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, value) - } else { - struct_start_event - } - }) - )) - } + Field::FieldString => Some(field.ser_wrap_default_attribute( + None, + quote!({ + if let Some(ref value) = self.#label { + struct_start_event.attr(#label_name, value) + } else { + struct_start_event + } + }), + )), Field::FieldBool | Field::FieldI8 | Field::FieldU8 @@ -64,57 +59,51 @@ pub fn serialize( | Field::FieldI64 | Field::FieldU64 | Field::FieldF32 - | Field::FieldF64 => { - Some(field.ser_wrap_default_attribute( - quote!(self.#label.map_or_else(|| String::new(), |v| v.to_string())), - quote!({ - if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, &yaserde_inner) - } else { - struct_start_event - } - }) - )) - } + | Field::FieldF64 => Some(field.ser_wrap_default_attribute( + Some(quote!(self.#label.map_or_else(|| String::new(), |v| v.to_string()))), + quote!({ + if let Some(ref value) = self.#label { + struct_start_event.attr(#label_name, &yaserde_inner) + } else { + struct_start_event + } + }), + )), Field::FieldVec { .. } => { let item_ident = Ident::new("yaserde_item", field.get_span()); let inner = enclose_formatted_characters(&item_ident, label_name); Some(field.ser_wrap_default_attribute( - quote!({}), + None, quote!({ if let Some(ref yaserde_list) = self.#label { for yaserde_item in yaserde_list.iter() { #inner } } - }) + }), )) } - Field::FieldStruct { .. } => { - Some(field.ser_wrap_default_attribute( - quote!(self.#label + Field::FieldStruct { .. } => Some(field.ser_wrap_default_attribute( + Some(quote!(self.#label .as_ref() - .map_or_else(|| Ok(String::new()), |v| yaserde::ser::to_string_content(v))?), - quote!({ - if let Some(ref yaserde_struct) = self.#label { - struct_start_event.attr(#label_name, &yaserde_inner) - } else { - struct_start_event - } - }) - )) - } + .map_or_else(|| Ok(String::new()), |v| yaserde::ser::to_string_content(v))?)), + quote!({ + if let Some(ref yaserde_struct) = self.#label { + struct_start_event.attr(#label_name, &yaserde_inner) + } else { + struct_start_event + } + }), + )), Field::FieldOption { .. } => unimplemented!(), }, - Field::FieldStruct { .. } => { - Some(field.ser_wrap_default_attribute( - quote!(yaserde::ser::to_string_content(&self.#label)?), - quote!({ - struct_start_event.attr(#label_name, &yaserde_inner) - }) - )) - } + Field::FieldStruct { .. } => Some(field.ser_wrap_default_attribute( + Some(quote!(yaserde::ser::to_string_content(&self.#label)?)), + quote!({ + struct_start_event.attr(#label_name, &yaserde_inner) + }), + )), Field::FieldVec { .. } => None, } }) @@ -124,25 +113,21 @@ pub fn serialize( let struct_inspector: TokenStream = data_struct .fields .iter() + .map(|field| YaSerdeField::new(field.clone())) + .filter(|field| !field.is_attribute()) .map(|field| { - let field_attrs = YaSerdeAttribute::parse(&field.attrs); - if Field::is_attribute(field) { - return None; - } - - let label = Field::label(field); - if Field::is_text_content(field) { + let label = field.label(); + if field.is_text_content() { return Some(quote!( let data_event = XmlEvent::characters(&self.#label); writer.write(data_event).map_err(|e| e.to_string())?; )); } - let label_name = Field::renamed_label(field, root_attributes); + let label_name = field.renamed_label(root_attributes); + let conditions = condition_generator(&label, &field); - let conditions = condition_generator(&label, &field_attrs); - - match Field::from(field) { + match field.get_type() { Field::FieldString | Field::FieldBool | Field::FieldI8 @@ -169,7 +154,7 @@ pub fn serialize( | Field::FieldU64 | Field::FieldF32 | Field::FieldF64 => { - let item_ident = Ident::new("yaserde_item", field.span()); + let item_ident = Ident::new("yaserde_item", field.get_span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { @@ -181,7 +166,7 @@ pub fn serialize( }) } Field::FieldVec { .. } => { - let item_ident = Ident::new("yaserde_item", field.span()); + let item_ident = Ident::new("yaserde_item", field.get_span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { @@ -194,7 +179,7 @@ pub fn serialize( } }) } - Field::FieldStruct { .. } => Some(if field_attrs.flatten { + Field::FieldStruct { .. } => Some(if field.is_flatten() { quote! { if let Some(ref item) = &self.#label { writer.set_start_event_name(None); @@ -214,7 +199,7 @@ pub fn serialize( _ => unimplemented!(), }, Field::FieldStruct { .. } => { - let (start_event, skip_start) = if field_attrs.flatten { + let (start_event, skip_start) = if field.is_flatten() { (quote!(None), true) } else { (quote!(Some(#label_name.to_string())), false) @@ -228,7 +213,7 @@ pub fn serialize( } Field::FieldVec { data_type } => match *data_type { Field::FieldString => { - let item_ident = Ident::new("yaserde_item", field.span()); + let item_ident = Ident::new("yaserde_item", field.get_span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { @@ -248,7 +233,7 @@ pub fn serialize( | Field::FieldU64 | Field::FieldF32 | Field::FieldF64 => { - let item_ident = Ident::new("yaserde_item", field.span()); + let item_ident = Ident::new("yaserde_item", field.get_span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { From 975baabd768ecc0d3d4fc68e5e181a1dc6a8205a Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Wed, 22 Apr 2020 19:04:43 +0200 Subject: [PATCH 6/7] remove root attribute, use rename --- yaserde/src/lib.rs | 4 +- yaserde/tests/default.rs | 8 ++-- yaserde/tests/enum.rs | 10 ++--- yaserde/tests/namespace.rs | 24 +++++------ yaserde/tests/serializer.rs | 22 +++++------ yaserde/tests/skip_if.rs | 2 +- yaserde_derive/src/common/attribute.rs | 55 ++++++++++++++++++++------ yaserde_derive/src/common/field.rs | 51 ++++-------------------- yaserde_derive/src/de/expand_struct.rs | 35 ++-------------- yaserde_derive/src/de/mod.rs | 8 ++-- yaserde_derive/src/ser/mod.rs | 19 +++++---- 11 files changed, 104 insertions(+), 134 deletions(-) diff --git a/yaserde/src/lib.rs b/yaserde/src/lib.rs index bc27947..6eedc66 100644 --- a/yaserde/src/lib.rs +++ b/yaserde/src/lib.rs @@ -144,7 +144,7 @@ mod testing { macro_rules! test_for_type { ($type:ty, $value:expr, $content:expr) => {{ #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "data")] + #[yaserde(rename = "data")] pub struct Data { item: $type, } @@ -166,7 +166,7 @@ mod testing { macro_rules! test_for_attribute_type { ($type: ty, $value: expr, $content: expr) => {{ #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "data")] + #[yaserde(rename = "data")] pub struct Data { #[yaserde(attribute)] item: $type, diff --git a/yaserde/tests/default.rs b/yaserde/tests/default.rs index 38fb151..c4ba308 100644 --- a/yaserde/tests/default.rs +++ b/yaserde/tests/default.rs @@ -13,7 +13,7 @@ fn default_field_string() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(default = "default_string")] background: String, @@ -42,7 +42,7 @@ fn default_field_boolean() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(default = "default_boolean")] background: bool, @@ -66,7 +66,7 @@ fn default_field_number() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(default = "default_number")] background: u8, @@ -90,7 +90,7 @@ fn default_attribute_string() { } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute, default = "default_string")] background: String, diff --git a/yaserde/tests/enum.rs b/yaserde/tests/enum.rs index ab96c42..cca4edf 100644 --- a/yaserde/tests/enum.rs +++ b/yaserde/tests/enum.rs @@ -9,13 +9,13 @@ use yaserde::{YaDeserialize, YaSerialize}; #[test] fn basic_enum() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { color: Color, } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "color")] + #[yaserde(rename = "color")] pub enum Color { White, Black, @@ -124,14 +124,14 @@ fn basic_enum() { #[test] fn attribute_enum() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute)] color: Color, } #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "color")] + #[yaserde(rename = "color")] pub enum Color { #[yaserde(rename = "pink")] Pink, @@ -153,7 +153,7 @@ fn attribute_enum() { #[test] fn unnamed_enum() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { color: Enum, } diff --git a/yaserde/tests/namespace.rs b/yaserde/tests/namespace.rs index 4025e90..dd53c9e 100644 --- a/yaserde/tests/namespace.rs +++ b/yaserde/tests/namespace.rs @@ -10,7 +10,7 @@ use yaserde::{YaDeserialize, YaSerialize}; fn struct_simple_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -41,7 +41,7 @@ fn struct_simple_namespace() { fn struct_multiple_namespaces() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain", namespace = "ns2: http://www.sample.com/ns/domain_2" @@ -73,7 +73,7 @@ fn struct_multiple_namespaces() { fn struct_partial_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -103,7 +103,7 @@ fn struct_partial_namespace() { fn struct_sub_namespace_definition() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain", namespace = "ns2: http://www.sample.com/ns/domain_2" @@ -206,7 +206,7 @@ fn struct_namespace_nested_defined_at_root() { fn struct_attribute_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", namespace = "ns1: http://www.sample.com/ns/domain1", namespace = "ns2: http://www.sample.com/ns/domain2" )] @@ -236,7 +236,7 @@ fn struct_attribute_namespace() { fn struct_implicit_default_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "tt", + rename = "tt", namespace = "http://www.w3.org/ns/ttml", namespace = "ttm: http://www.w3.org/ns/ttml#metadata" )] @@ -258,7 +258,7 @@ fn struct_implicit_default_namespace() { fn struct_explicit_default_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "tt", + rename = "tt", default_namespace = "ttml", namespace = "ttml: http://www.w3.org/ns/ttml", namespace = "ttm: http://www.w3.org/ns/ttml#metadata" @@ -281,7 +281,7 @@ fn struct_explicit_default_namespace() { fn struct_default_namespace_via_attribute_with_prefix() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "tt", + rename = "tt", prefix = "TTML", default_namespace = "TTML", namespace = "TTML: http://www.w3.org/ns/ttml", @@ -305,7 +305,7 @@ fn struct_default_namespace_via_attribute_with_prefix() { fn enum_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -335,7 +335,7 @@ fn enum_namespace() { fn enum_multi_namespaces() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", namespace = "ns1: http://www.sample.com/ns/domain1", namespace = "ns2: http://www.sample.com/ns/domain2" )] @@ -376,7 +376,7 @@ fn enum_multi_namespaces() { fn enum_attribute_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "root", + rename = "root", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain" )] @@ -415,7 +415,7 @@ fn enum_attribute_namespace() { fn struct_bad_namespace() { #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[yaserde( - root = "book", + rename = "book", prefix = "ns", namespace = "ns: http://www.sample.com/ns/domain", namespace = "ns2: http://www.sample.com/ns/domain_2" diff --git a/yaserde/tests/serializer.rs b/yaserde/tests/serializer.rs index 2814f81..01b7921 100644 --- a/yaserde/tests/serializer.rs +++ b/yaserde/tests/serializer.rs @@ -9,7 +9,7 @@ use yaserde::YaSerialize; #[test] fn ser_basic() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { item: String, } @@ -25,7 +25,7 @@ fn ser_basic() { #[test] fn ser_list_of_items() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { items: Vec, } @@ -38,13 +38,13 @@ fn ser_list_of_items() { serialize_and_validate!(model, content); #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStructOfStruct { items: Vec, } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "items")] + #[yaserde(rename = "items")] pub struct SubStruct { field: String, } @@ -68,7 +68,7 @@ fn ser_list_of_items() { #[test] fn ser_attributes() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute)] item: String, @@ -76,7 +76,7 @@ fn ser_attributes() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "sub")] + #[yaserde(rename = "sub")] pub struct SubStruct { #[yaserde(attribute)] subitem: String, @@ -167,7 +167,7 @@ fn ser_attributes_complex() { #[test] fn ser_rename() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute, rename = "Item")] item: String, @@ -178,7 +178,7 @@ fn ser_rename() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "sub")] + #[yaserde(rename = "sub")] pub struct SubStruct { #[yaserde(attribute, rename = "sub_item")] subitem: String, @@ -214,7 +214,7 @@ fn ser_rename() { #[test] fn ser_text_content_with_attributes() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde(attribute, rename = "Item")] item: String, @@ -223,7 +223,7 @@ fn ser_text_content_with_attributes() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "sub")] + #[yaserde(rename = "sub")] pub struct SubStruct { #[yaserde(attribute, rename = "sub_item")] subitem: String, @@ -263,7 +263,7 @@ fn ser_text_content_with_attributes() { #[test] fn ser_name_issue_21() { #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { name: String, } diff --git a/yaserde/tests/skip_if.rs b/yaserde/tests/skip_if.rs index ed45cb2..e7c853e 100644 --- a/yaserde/tests/skip_if.rs +++ b/yaserde/tests/skip_if.rs @@ -13,7 +13,7 @@ fn skip_serializing_if_for_struct() { } #[derive(YaSerialize, PartialEq, Debug)] - #[yaserde(root = "base")] + #[yaserde(rename = "base")] pub struct XmlStruct { #[yaserde( skip_serializing_if = "check_string_function", diff --git a/yaserde_derive/src/common/attribute.rs b/yaserde_derive/src/common/attribute.rs index 6504dad..45b1138 100644 --- a/yaserde_derive/src/common/attribute.rs +++ b/yaserde_derive/src/common/attribute.rs @@ -1,6 +1,4 @@ -use proc_macro2::token_stream::IntoIter; -use proc_macro2::Delimiter; -use proc_macro2::TokenTree; +use proc_macro2::{token_stream::IntoIter, Delimiter, TokenStream, TokenTree}; use std::collections::BTreeMap; use syn::Attribute; @@ -12,7 +10,6 @@ pub struct YaSerdeAttribute { pub flatten: bool, pub namespaces: BTreeMap, pub prefix: Option, - pub root: Option, pub rename: Option, pub skip_serializing_if: Option, pub text: bool, @@ -41,7 +38,6 @@ impl YaSerdeAttribute { let mut namespaces = BTreeMap::new(); let mut prefix = None; let mut rename = None; - let mut root = None; let mut skip_serializing_if = None; let mut text = false; @@ -84,9 +80,6 @@ impl YaSerdeAttribute { "rename" => { rename = get_value(&mut attr_iter); } - "root" => { - root = get_value(&mut attr_iter); - } "skip_serializing_if" => { skip_serializing_if = get_value(&mut attr_iter); } @@ -110,11 +103,51 @@ impl YaSerdeAttribute { namespaces, prefix, rename, - root, skip_serializing_if, text, } } + + pub fn get_namespace_matching( + &self, + prefix: &Option, + element_namespace: TokenStream, + element_name: TokenStream, + take_root_prefix: bool + ) -> TokenStream { + let configured_prefix = + if take_root_prefix { + self.prefix.clone() + } else { + prefix.clone() + }; + + let namespaces_matches : TokenStream = + self + .namespaces + .iter() + .map(|(prefix, namespace)| { + if configured_prefix == Some(prefix.to_string()) { + Some(quote!(#namespace => {})) + } else { + None + } + }) + .filter_map(|x| x) + .collect(); + + quote!( + if let Some(namespace) = #element_namespace { + match namespace.as_str() { + #namespaces_matches + bad_namespace => { + let msg = format!("bad namespace for {}, found {}", #element_name, bad_namespace); + return Err(msg); + } + } + } + ) + } } #[test] @@ -130,7 +163,6 @@ fn parse_empty_attributes() { flatten: false, namespaces: BTreeMap::new(), prefix: None, - root: None, rename: None, skip_serializing_if: None, text: false, @@ -180,7 +212,6 @@ fn parse_attributes() { flatten: false, namespaces: BTreeMap::new(), prefix: None, - root: None, rename: None, skip_serializing_if: None, text: false, @@ -205,7 +236,6 @@ fn parse_attributes_with_values() { arguments: PathArguments::None, }); - // #[()] let attributes = vec![Attribute { pound_token: Pound { spans: [Span::call_site()], @@ -234,7 +264,6 @@ fn parse_attributes_with_values() { flatten: true, namespaces, prefix: None, - root: None, rename: None, skip_serializing_if: None, text: false, diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index e2faa0a..241bf2c 100644 --- a/yaserde_derive/src/common/field.rs +++ b/yaserde_derive/src/common/field.rs @@ -118,19 +118,13 @@ impl YaSerdeField { .map(|skip_serializing_if| Ident::new(&skip_serializing_if, self.get_span())) } - pub fn get_namespace_matching(&self, root_attributes: &YaSerdeAttribute) -> TokenStream { - root_attributes - .namespaces - .iter() - .map(|(prefix, namespace)| { - if self.attributes.prefix == Some(prefix.to_string()) { - Some(quote!(#namespace => {})) - } else { - None - } - }) - .filter_map(|x| x) - .collect() + pub fn get_namespace_matching( + &self, + root_attributes: &YaSerdeAttribute, + element_namespace: TokenStream, + element_name: TokenStream, + ) -> TokenStream { + root_attributes.get_namespace_matching(&self.attributes.prefix, element_namespace, element_name, false) } pub fn ser_wrap_default_attribute( @@ -184,37 +178,6 @@ pub enum Field { } impl Field { - pub fn is_attribute(token_field: &syn::Field) -> bool { - YaSerdeAttribute::parse(&token_field.attrs).attribute - } - - pub fn is_text_content(token_field: &syn::Field) -> bool { - YaSerdeAttribute::parse(&token_field.attrs).text - } - - pub fn label(token_field: &syn::Field) -> Option { - token_field.ident.clone() - } - - pub fn renamed_label(token_field: &syn::Field, root_attributes: &YaSerdeAttribute) -> String { - let attributes = YaSerdeAttribute::parse(&token_field.attrs); - - let prefix = if root_attributes.default_namespace == attributes.prefix { - "".to_string() - } else { - attributes - .prefix - .clone() - .map_or("".to_string(), |prefix| prefix + ":") - }; - - let label = attributes - .rename - .unwrap_or_else(|| token_field.ident.as_ref().unwrap().to_string()); - - format!("{}{}", prefix, label) - } - pub fn get_simple_type_visitor(&self) -> TokenStream { let ident = format_ident!("visit_{}", self.to_string()); quote! {#ident} diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 0bc283f..0a4bffd 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -9,18 +9,7 @@ pub fn parse( root: &str, root_attributes: &YaSerdeAttribute, ) -> TokenStream { - let namespaces_matches: TokenStream = root_attributes - .namespaces - .iter() - .map(|(prefix, namespace)| { - if root_attributes.prefix.as_ref() == Some(prefix) { - Some(quote!(#namespace => {})) - } else { - None - } - }) - .filter_map(|x| x) - .collect(); + let namespaces_matching = root_attributes.get_namespace_matching(&None, quote!(struct_namespace), quote!(named_element), true); let variables: TokenStream = data_struct .fields @@ -330,15 +319,7 @@ pub fn parse( debug!("Struct: start to parse {:?}", named_element); if reader.depth() == 0 { - if let Some(ref namespace) = struct_namespace { - match namespace.as_str() { - #namespaces_matches - bad_ns => { - let msg = format!("bad namespace for {}, found {}", named_element, bad_ns); - return Err(msg); - } - } - } + #namespaces_matching } #variables @@ -419,21 +400,13 @@ fn build_call_visitor( let label_name = field.renamed_label_without_namespace(); let visitor_label = build_visitor_ident(&label_name, field.get_span(), None); - let namespaces_matches = field.get_namespace_matching(root_attributes); + let namespaces_matching = field.get_namespace_matching(root_attributes, quote!(name.namespace.as_ref()), quote!(name.local_name.as_str())); Some(quote! { #label_name => { let visitor = #visitor_label{}; - if let Some(namespace) = name.namespace.as_ref() { - match namespace.as_str() { - #namespaces_matches - bad_ns => { - let msg = format!("bad field namespace for {}, found {}", name.local_name.as_str(), bad_ns); - return Err(msg); - } - } - } + #namespaces_matching let result = reader.read_inner_value::<#field_type, _>(|reader| { if let Ok(XmlEvent::Characters(s)) = reader.peek() { diff --git a/yaserde_derive/src/de/mod.rs b/yaserde_derive/src/de/mod.rs index ec9ff56..a4c4355 100644 --- a/yaserde_derive/src/de/mod.rs +++ b/yaserde_derive/src/de/mod.rs @@ -12,14 +12,14 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result { - expand_struct::parse(data_struct, name, &root, &root_attrs) + expand_struct::parse(data_struct, name, &root_name, &root_attributes) } - syn::Data::Enum(ref data_enum) => expand_enum::parse(data_enum, name, &root, &root_attrs), + syn::Data::Enum(ref data_enum) => expand_enum::parse(data_enum, name, &root_name, &root_attributes), syn::Data::Union(ref _data_union) => unimplemented!(), }; diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs index c294514..23d8353 100644 --- a/yaserde_derive/src/ser/mod.rs +++ b/yaserde_derive/src/ser/mod.rs @@ -15,25 +15,30 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result { - expand_struct::serialize(data_struct, name, &root, &root_attrs) + expand_struct::serialize(data_struct, name, &root_name, &root_attributes) + } + syn::Data::Enum(ref data_enum) => { + expand_enum::serialize(data_enum, name, &root_name, &root_attributes) } - syn::Data::Enum(ref data_enum) => expand_enum::serialize(data_enum, name, &root, &root_attrs), syn::Data::Union(ref _data_union) => unimplemented!(), }; From e2a2779f71428aa0ca8fcbd37eca0c0401a3b304 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Wed, 22 Apr 2020 19:05:13 +0200 Subject: [PATCH 7/7] format code --- yaserde_derive/src/common/attribute.rs | 40 ++++++++++++-------------- yaserde_derive/src/common/field.rs | 9 ++++-- yaserde_derive/src/de/expand_struct.rs | 13 +++++++-- yaserde_derive/src/de/mod.rs | 9 ++++-- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/yaserde_derive/src/common/attribute.rs b/yaserde_derive/src/common/attribute.rs index 45b1138..2896bab 100644 --- a/yaserde_derive/src/common/attribute.rs +++ b/yaserde_derive/src/common/attribute.rs @@ -113,28 +113,26 @@ impl YaSerdeAttribute { prefix: &Option, element_namespace: TokenStream, element_name: TokenStream, - take_root_prefix: bool - ) -> TokenStream { - let configured_prefix = - if take_root_prefix { - self.prefix.clone() - } else { - prefix.clone() - }; + take_root_prefix: bool, + ) -> TokenStream { + let configured_prefix = if take_root_prefix { + self.prefix.clone() + } else { + prefix.clone() + }; - let namespaces_matches : TokenStream = - self - .namespaces - .iter() - .map(|(prefix, namespace)| { - if configured_prefix == Some(prefix.to_string()) { - Some(quote!(#namespace => {})) - } else { - None - } - }) - .filter_map(|x| x) - .collect(); + let namespaces_matches: TokenStream = self + .namespaces + .iter() + .map(|(prefix, namespace)| { + if configured_prefix == Some(prefix.to_string()) { + Some(quote!(#namespace => {})) + } else { + None + } + }) + .filter_map(|x| x) + .collect(); quote!( if let Some(namespace) = #element_namespace { diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index 241bf2c..0a00087 100644 --- a/yaserde_derive/src/common/field.rs +++ b/yaserde_derive/src/common/field.rs @@ -123,8 +123,13 @@ impl YaSerdeField { root_attributes: &YaSerdeAttribute, element_namespace: TokenStream, element_name: TokenStream, - ) -> TokenStream { - root_attributes.get_namespace_matching(&self.attributes.prefix, element_namespace, element_name, false) + ) -> TokenStream { + root_attributes.get_namespace_matching( + &self.attributes.prefix, + element_namespace, + element_name, + false, + ) } pub fn ser_wrap_default_attribute( diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 0a4bffd..bd9c718 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -9,7 +9,12 @@ pub fn parse( root: &str, root_attributes: &YaSerdeAttribute, ) -> TokenStream { - let namespaces_matching = root_attributes.get_namespace_matching(&None, quote!(struct_namespace), quote!(named_element), true); + let namespaces_matching = root_attributes.get_namespace_matching( + &None, + quote!(struct_namespace), + quote!(named_element), + true, + ); let variables: TokenStream = data_struct .fields @@ -400,7 +405,11 @@ fn build_call_visitor( let label_name = field.renamed_label_without_namespace(); let visitor_label = build_visitor_ident(&label_name, field.get_span(), None); - let namespaces_matching = field.get_namespace_matching(root_attributes, quote!(name.namespace.as_ref()), quote!(name.local_name.as_str())); + let namespaces_matching = field.get_namespace_matching( + root_attributes, + quote!(name.namespace.as_ref()), + quote!(name.local_name.as_str()), + ); Some(quote! { #label_name => { diff --git a/yaserde_derive/src/de/mod.rs b/yaserde_derive/src/de/mod.rs index a4c4355..a6df2b3 100644 --- a/yaserde_derive/src/de/mod.rs +++ b/yaserde_derive/src/de/mod.rs @@ -13,13 +13,18 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result { expand_struct::parse(data_struct, name, &root_name, &root_attributes) } - syn::Data::Enum(ref data_enum) => expand_enum::parse(data_enum, name, &root_name, &root_attributes), + syn::Data::Enum(ref data_enum) => { + expand_enum::parse(data_enum, name, &root_name, &root_attributes) + } syn::Data::Union(ref _data_union) => unimplemented!(), };