Implement flatten (ser)
This commit is contained in:
parent
cc7cf76a45
commit
6063ff393a
@ -11,7 +11,15 @@ use yaserde::YaSerialize;
|
|||||||
macro_rules! convert_and_validate {
|
macro_rules! convert_and_validate {
|
||||||
($model: expr, $content: expr) => {
|
($model: expr, $content: expr) => {
|
||||||
let data: Result<String, String> = to_string(&$model);
|
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>";
|
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);
|
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! {
|
FieldType::FieldTypeStruct { .. } => Some(if field_attrs.flatten {
|
||||||
if let Some(ref item) = &self.#label {
|
quote! {
|
||||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
if let Some(ref item) = &self.#label {
|
||||||
writer.set_skip_start_end(false);
|
writer.set_start_event_name(None);
|
||||||
item.serialize(writer)?;
|
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!(),
|
_ => unimplemented!(),
|
||||||
},
|
},
|
||||||
FieldType::FieldTypeStruct { .. } => Some(quote! {
|
FieldType::FieldTypeStruct { .. } => Some(if field_attrs.flatten {
|
||||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
quote! {
|
||||||
writer.set_skip_start_end(false);
|
writer.set_start_event_name(None);
|
||||||
self.#label.serialize(writer)?;
|
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::FieldTypeVec { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeString => {
|
FieldType::FieldTypeString => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user