Merge pull request #32 from DmitrySamoylov/fix-custom-serializer
Fix custom serializer
This commit is contained in:
commit
f8ffe8c88e
@ -570,3 +570,60 @@ fn de_name_issue_21() {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn de_custom() {
|
||||
#[derive(Default, PartialEq, Debug, YaDeserialize)]
|
||||
struct Date {
|
||||
#[yaserde(rename = "Year")]
|
||||
year: i32,
|
||||
#[yaserde(rename = "Month")]
|
||||
month: i32,
|
||||
#[yaserde(rename = "Day")]
|
||||
day: Day,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Debug)]
|
||||
struct Day {
|
||||
value: i32,
|
||||
}
|
||||
|
||||
impl YaDeserialize for Day {
|
||||
fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, String> {
|
||||
use std::str::FromStr;
|
||||
|
||||
if let xml::reader::XmlEvent::StartElement { name, .. } = reader.peek()?.to_owned() {
|
||||
let expected_name = String::from("Day");
|
||||
if name.local_name != expected_name {
|
||||
return Err(format!(
|
||||
"Wrong StartElement name: {}, expected: {}",
|
||||
name, expected_name
|
||||
));
|
||||
}
|
||||
let _next = reader.next_event();
|
||||
} else {
|
||||
return Err("StartElement missing".to_string());
|
||||
}
|
||||
|
||||
if let xml::reader::XmlEvent::Characters(text) = reader.peek()?.to_owned() {
|
||||
Ok(Day {
|
||||
value: 2 * i32::from_str(&text).unwrap(),
|
||||
})
|
||||
} else {
|
||||
Err("Characters missing".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Date><Year>2020</Year><Month>01</Month><Day>11</Day></Date>";
|
||||
let model: Date = from_str(content).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
model,
|
||||
Date {
|
||||
year: 2020,
|
||||
month: 1,
|
||||
day: Day { value: 11 * 2 }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate xml;
|
||||
extern crate yaserde;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate xml;
|
||||
extern crate yaserde;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate xml;
|
||||
extern crate yaserde;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate xml;
|
||||
extern crate yaserde;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate xml;
|
||||
extern crate yaserde;
|
||||
@ -440,3 +439,40 @@ fn ser_name_issue_21() {
|
||||
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><name>something</name></base>";
|
||||
convert_and_validate!(model, content);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ser_custom() {
|
||||
#[derive(Default, PartialEq, Debug, YaSerialize)]
|
||||
struct Date {
|
||||
#[yaserde(rename = "Year")]
|
||||
year: i32,
|
||||
#[yaserde(rename = "Month")]
|
||||
month: i32,
|
||||
#[yaserde(rename = "Day")]
|
||||
day: Day,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Debug)]
|
||||
struct Day {
|
||||
value: i32,
|
||||
}
|
||||
|
||||
impl YaSerialize for Day {
|
||||
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) -> Result<(), String> {
|
||||
let _ret = writer.write(xml::writer::XmlEvent::start_element("DoubleDay"));
|
||||
let _ret = writer.write(xml::writer::XmlEvent::characters(
|
||||
&(self.value * 2).to_string(),
|
||||
));
|
||||
let _ret = writer.write(xml::writer::XmlEvent::end_element());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let model = Date {
|
||||
year: 2020,
|
||||
month: 1,
|
||||
day: Day { value: 5 },
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
@ -77,35 +77,22 @@ pub fn serialize(
|
||||
}
|
||||
}),
|
||||
Some(FieldType::FieldTypeStruct { .. }) => Some(quote! {
|
||||
let struct_start_event = XmlEvent::start_element(#field_label_name);
|
||||
let _ret = writer.write(struct_start_event);
|
||||
|
||||
match self {
|
||||
&#name::#label{ref #field_label, ..} => {
|
||||
writer.set_skip_start_end(true);
|
||||
if let Err(msg) = #field_label.serialize(writer) {
|
||||
return Err(msg);
|
||||
};
|
||||
writer.set_start_event_name(Some(#field_label_name.to_string()));
|
||||
writer.set_skip_start_end(false);
|
||||
#field_label.serialize(writer)?;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let struct_end_event = XmlEvent::end_element();
|
||||
let _ret = writer.write(struct_end_event);
|
||||
}),
|
||||
Some(FieldType::FieldTypeVec { .. }) => Some(quote! {
|
||||
match self {
|
||||
&#name::#label{ref #field_label, ..} => {
|
||||
for item in #field_label {
|
||||
let struct_start_event = XmlEvent::start_element(#field_label_name);
|
||||
let _ret = writer.write(struct_start_event);
|
||||
|
||||
writer.set_skip_start_end(true);
|
||||
if let Err(msg) = item.serialize(writer) {
|
||||
return Err(msg);
|
||||
};
|
||||
let struct_end_event = XmlEvent::end_element();
|
||||
let _ret = writer.write(struct_end_event);
|
||||
writer.set_start_event_name(Some(#field_label_name.to_string()));
|
||||
writer.set_skip_start_end(false);
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
@ -163,10 +150,9 @@ pub fn serialize(
|
||||
});
|
||||
|
||||
let serialize = quote! {
|
||||
writer.set_start_event_name(None);
|
||||
writer.set_skip_start_end(true);
|
||||
if let Err(msg) = item.serialize(writer) {
|
||||
return Err(msg);
|
||||
};
|
||||
item.serialize(writer)?;
|
||||
};
|
||||
|
||||
let write_sub_type = |data_type| {
|
||||
@ -255,27 +241,27 @@ pub fn serialize(
|
||||
#[allow(unused_variables)]
|
||||
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>)
|
||||
-> Result<(), String> {
|
||||
if let Some(label) = writer.get_start_event_name() {
|
||||
let struct_start_event = XmlEvent::start_element(label.as_ref());
|
||||
let _ret = writer.write(struct_start_event);
|
||||
return Ok(());
|
||||
}
|
||||
error!("Enum: start to expand {:?}", #root);
|
||||
let skip = writer.skip_start_end();
|
||||
|
||||
if !writer.skip_start_end() {
|
||||
let struct_start_event = XmlEvent::start_element(#root)#add_namespaces;
|
||||
let _ret = writer.write(struct_start_event);
|
||||
if !skip {
|
||||
if let Some(label) = writer.get_start_event_name() {
|
||||
let struct_start_event = XmlEvent::start_element(label.as_ref());
|
||||
let _ret = writer.write(struct_start_event);
|
||||
} else {
|
||||
let struct_start_event = XmlEvent::start_element(#root)#add_namespaces;
|
||||
let _ret = writer.write(struct_start_event);
|
||||
}
|
||||
}
|
||||
|
||||
match self {
|
||||
#write_enum_content
|
||||
}
|
||||
|
||||
if !writer.skip_start_end() {
|
||||
if !skip {
|
||||
let struct_end_event = XmlEvent::end_element();
|
||||
let _ret = writer.write(struct_end_event);
|
||||
}
|
||||
writer.set_skip_start_end(false);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,24 +361,8 @@ pub fn serialize(
|
||||
Some(&FieldType::FieldTypeStruct { .. }) => Some(quote! {
|
||||
if let Some(ref item) = &self.#label {
|
||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
||||
match item.serialize(writer) {
|
||||
Ok(()) => {},
|
||||
Err(msg) => {
|
||||
return Err(msg);
|
||||
},
|
||||
};
|
||||
writer.set_start_event_name(None);
|
||||
|
||||
writer.set_skip_start_end(true);
|
||||
match item.serialize(writer) {
|
||||
Ok(()) => {},
|
||||
Err(msg) => {
|
||||
return Err(msg);
|
||||
},
|
||||
};
|
||||
|
||||
let end_event = XmlEvent::end_element();
|
||||
let _ret = writer.write(end_event);
|
||||
writer.set_skip_start_end(false);
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
}),
|
||||
_ => unimplemented!(),
|
||||
@ -386,24 +370,8 @@ pub fn serialize(
|
||||
}
|
||||
Some(FieldType::FieldTypeStruct { .. }) => Some(quote! {
|
||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
||||
match self.#label.serialize(writer) {
|
||||
Ok(()) => {},
|
||||
Err(msg) => {
|
||||
return Err(msg);
|
||||
},
|
||||
};
|
||||
writer.set_start_event_name(None);
|
||||
|
||||
writer.set_skip_start_end(true);
|
||||
match self.#label.serialize(writer) {
|
||||
Ok(()) => {},
|
||||
Err(msg) => {
|
||||
return Err(msg);
|
||||
},
|
||||
};
|
||||
|
||||
let end_event = XmlEvent::end_element();
|
||||
let _ret = writer.write(end_event);
|
||||
writer.set_skip_start_end(false);
|
||||
self.#label.serialize(writer)?;
|
||||
}),
|
||||
Some(FieldType::FieldTypeVec { data_type }) => {
|
||||
let dt = Box::into_raw(data_type);
|
||||
@ -441,25 +409,17 @@ pub fn serialize(
|
||||
Some(&FieldType::FieldTypeOption { .. }) => Some(quote! {
|
||||
for item in &self.#label {
|
||||
if let Some(value) = item {
|
||||
writer.set_start_event_name(None);
|
||||
writer.set_skip_start_end(false);
|
||||
match value.serialize(writer) {
|
||||
Ok(()) => {},
|
||||
Err(msg) => {
|
||||
return Err(msg);
|
||||
},
|
||||
};
|
||||
value.serialize(writer)?;
|
||||
}
|
||||
}
|
||||
}),
|
||||
Some(&FieldType::FieldTypeStruct { .. }) => Some(quote! {
|
||||
for item in &self.#label {
|
||||
writer.set_start_event_name(None);
|
||||
writer.set_skip_start_end(false);
|
||||
match item.serialize(writer) {
|
||||
Ok(()) => {},
|
||||
Err(msg) => {
|
||||
return Err(msg);
|
||||
},
|
||||
};
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
}),
|
||||
Some(&FieldType::FieldTypeVec { .. }) => {
|
||||
@ -487,18 +447,18 @@ pub fn serialize(
|
||||
#[allow(unused_variables)]
|
||||
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>)
|
||||
-> Result<(), String> {
|
||||
if let Some(label) = writer.get_start_event_name() {
|
||||
let struct_start_event = XmlEvent::start_element(label.as_ref());
|
||||
#build_attributes
|
||||
let _ret = writer.write(struct_start_event);
|
||||
return Ok(())
|
||||
}
|
||||
error!("Struct: start to expand {:?}", #root);
|
||||
let skip = writer.skip_start_end();
|
||||
|
||||
if !skip {
|
||||
let struct_start_event = XmlEvent::start_element(#root)#add_namespaces;
|
||||
#build_attributes
|
||||
let _ret = writer.write(struct_start_event);
|
||||
if let Some(label) = writer.get_start_event_name() {
|
||||
let struct_start_event = XmlEvent::start_element(label.as_ref());
|
||||
#build_attributes
|
||||
let _ret = writer.write(struct_start_event);
|
||||
} else {
|
||||
let struct_start_event = XmlEvent::start_element(#root)#add_namespaces;
|
||||
#build_attributes
|
||||
let _ret = writer.write(struct_start_event);
|
||||
}
|
||||
}
|
||||
|
||||
#struct_inspector
|
||||
@ -507,6 +467,7 @@ pub fn serialize(
|
||||
let struct_end_event = XmlEvent::end_element();
|
||||
let _ret = writer.write(struct_end_event);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user