diff --git a/yaserde/tests/serializer.rs b/yaserde/tests/serializer.rs index 66480e0..eeb9c54 100644 --- a/yaserde/tests/serializer.rs +++ b/yaserde/tests/serializer.rs @@ -11,7 +11,15 @@ 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))); + assert_eq!( + data, + Ok( + String::from($content) + .split("\n") + .map(|s| s.trim()) + .collect::() + ) + ); }; } @@ -489,3 +497,87 @@ fn ser_custom() { let content = "2020110"; convert_and_validate!(model, content); } + +#[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 + "#; + + convert_and_validate!(model, content); +} diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 0ecd409..ed208d4 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -327,19 +327,37 @@ pub fn serialize( }) } } - FieldType::FieldTypeStruct { .. } => Some(quote! { - if let Some(ref item) = &self.#label { - writer.set_start_event_name(Some(#label_name.to_string())); - writer.set_skip_start_end(false); - item.serialize(writer)?; + FieldType::FieldTypeStruct { .. } => Some(if field_attrs.flatten { + quote! { + if let Some(ref item) = &self.#label { + writer.set_start_event_name(None); + writer.set_skip_start_end(true); + item.serialize(writer)?; + } + } + } else { + quote! { + if let Some(ref item) = &self.#label { + writer.set_start_event_name(Some(#label_name.to_string())); + writer.set_skip_start_end(false); + item.serialize(writer)?; + } } }), _ => unimplemented!(), }, - FieldType::FieldTypeStruct { .. } => Some(quote! { - writer.set_start_event_name(Some(#label_name.to_string())); - writer.set_skip_start_end(false); - self.#label.serialize(writer)?; + FieldType::FieldTypeStruct { .. } => Some(if field_attrs.flatten { + quote! { + writer.set_start_event_name(None); + writer.set_skip_start_end(true); + self.#label.serialize(writer)?; + } + } else { + quote! { + writer.set_start_event_name(Some(#label_name.to_string())); + writer.set_skip_start_end(false); + self.#label.serialize(writer)?; + } }), FieldType::FieldTypeVec { data_type } => match *data_type { FieldType::FieldTypeString => {