Implement flatten (ser)
This commit is contained in:
parent
cc7cf76a45
commit
6063ff393a
@ -11,7 +11,15 @@ use yaserde::YaSerialize;
|
||||
macro_rules! convert_and_validate {
|
||||
($model: expr, $content: expr) => {
|
||||
let data: Result<String, String> = to_string(&$model);
|
||||
assert_eq!(data, Ok(String::from($content)));
|
||||
assert_eq!(
|
||||
data,
|
||||
Ok(
|
||||
String::from($content)
|
||||
.split("\n")
|
||||
.map(|s| s.trim())
|
||||
.collect::<String>()
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -489,3 +497,87 @@ fn ser_custom() {
|
||||
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Date><Year>2020</Year><Month>1</Month><DoubleDay>10</DoubleDay></Date>";
|
||||
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<OptionalExtra>,
|
||||
}
|
||||
|
||||
#[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<String>),
|
||||
#[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#"
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<DateTime>
|
||||
<year>2020</year>
|
||||
<month>1</month>
|
||||
<day>1</day>
|
||||
<week>1</week>
|
||||
<century>21</century>
|
||||
<lunar_day>1</lunar_day>
|
||||
<time>10:40:03</time>
|
||||
<holidays>New Year's Day</holidays>
|
||||
<holidays>Novy God Day</holidays>
|
||||
<holidays>Polar Bear Swim Day</holidays>
|
||||
</DateTime>"#;
|
||||
|
||||
convert_and_validate!(model, content);
|
||||
}
|
||||
|
||||
@ -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 => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user