Add serialization for enums with unnamed fields (#8)
This commit is contained in:
parent
d277d5137b
commit
95f826b41f
@ -299,6 +299,132 @@ fn ser_attribute_enum() {
|
|||||||
convert_and_validate!(model, content);
|
convert_and_validate!(model, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ser_unnamed_enum() {
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
#[yaserde(root = "base")]
|
||||||
|
pub struct XmlStruct {
|
||||||
|
color: Enum,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug, Default)]
|
||||||
|
pub struct OtherStruct {
|
||||||
|
fi: i32,
|
||||||
|
se: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
pub enum Enum {
|
||||||
|
Simple,
|
||||||
|
Field(String),
|
||||||
|
FullPath(std::string::String),
|
||||||
|
Integer(i32),
|
||||||
|
UserStruct(OtherStruct),
|
||||||
|
OptionString(Option<String>),
|
||||||
|
OptionUserStruct(Option<OtherStruct>),
|
||||||
|
Strings(Vec<String>),
|
||||||
|
Ints(Vec<i32>),
|
||||||
|
Structs(Vec<OtherStruct>),
|
||||||
|
#[yaserde(rename = "renamed")]
|
||||||
|
ToRename(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Enum {
|
||||||
|
fn default() -> Enum {
|
||||||
|
Enum::Simple
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::Field(String::from("some_text")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><Field>some_text</Field></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::FullPath(String::from("some_text")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><FullPath>some_text</FullPath></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::Integer(56),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content =
|
||||||
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><Integer>56</Integer></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::UserStruct(OtherStruct { fi: 24, se: 42 }),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><UserStruct><fi>24</fi><se>42</se></UserStruct></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::OptionString(Some(String::from("some_text"))),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><OptionString>some_text</OptionString></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::OptionString(None),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color /></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::OptionUserStruct(Some(OtherStruct { fi: 12, se: 23 })),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><OptionUserStruct><fi>12</fi><se>23</se></OptionUserStruct></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::OptionUserStruct(None),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color /></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::Strings(vec![String::from("abc"), String::from("def")]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><Strings>abc</Strings><Strings>def</Strings></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::Ints(vec![23, 45]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><Ints>23</Ints><Ints>45</Ints></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::Structs(vec![
|
||||||
|
OtherStruct { fi: 12, se: 23 },
|
||||||
|
OtherStruct { fi: 34, se: 45 },
|
||||||
|
]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><Structs><fi>12</fi><se>23</se></Structs><Structs><fi>34</fi><se>45</se></Structs></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
|
||||||
|
let model = XmlStruct {
|
||||||
|
color: Enum::ToRename(87),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content =
|
||||||
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><renamed>87</renamed></color></base>";
|
||||||
|
convert_and_validate!(model, content);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ser_name_issue_21() {
|
fn ser_name_issue_21() {
|
||||||
#[derive(YaSerialize, PartialEq, Debug)]
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
|||||||
@ -127,7 +127,104 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Fields::Unnamed(ref _fields) => unimplemented!(),
|
Fields::Unnamed(ref fields) => {
|
||||||
|
let enum_fields: TokenStream = fields
|
||||||
|
.unnamed
|
||||||
|
.iter()
|
||||||
|
.map(|field| {
|
||||||
|
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||||
|
if field_attrs.attribute {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let field_label_name = renamed_label.to_string();
|
||||||
|
|
||||||
|
let write_element = |action: &TokenStream| {
|
||||||
|
quote! {
|
||||||
|
let struct_start_event = XmlEvent::start_element(#field_label_name);
|
||||||
|
let _ret = writer.write(struct_start_event);
|
||||||
|
|
||||||
|
#action
|
||||||
|
|
||||||
|
let struct_end_event = XmlEvent::end_element();
|
||||||
|
let _ret = writer.write(struct_end_event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let write_string_chars = quote! {
|
||||||
|
let data_event = XmlEvent::characters(item);
|
||||||
|
let _ret = writer.write(data_event);
|
||||||
|
};
|
||||||
|
|
||||||
|
let write_simple_type = write_element("e! {
|
||||||
|
let s = item.to_string();
|
||||||
|
let data_event = XmlEvent::characters(&s);
|
||||||
|
let _ret = writer.write(data_event);
|
||||||
|
});
|
||||||
|
|
||||||
|
let serialize = quote! {
|
||||||
|
writer.set_skip_start_end(true);
|
||||||
|
if let Err(msg) = item.serialize(writer) {
|
||||||
|
return Err(msg);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let write_sub_type = |data_type| {
|
||||||
|
write_element(match data_type {
|
||||||
|
FieldType::FieldTypeString => &write_string_chars,
|
||||||
|
_ => &serialize,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let match_field = |write: &TokenStream| {
|
||||||
|
quote! {
|
||||||
|
match self {
|
||||||
|
&#name::#label(ref item) => {
|
||||||
|
#write
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match get_field_type(field) {
|
||||||
|
Some(FieldType::FieldTypeOption { data_type }) => {
|
||||||
|
let write = write_sub_type(*data_type);
|
||||||
|
|
||||||
|
Some(match_field("e! {
|
||||||
|
if let Some(item) = item {
|
||||||
|
#write
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Some(FieldType::FieldTypeVec { data_type }) => {
|
||||||
|
let write = write_sub_type(*data_type);
|
||||||
|
|
||||||
|
Some(match_field("e! {
|
||||||
|
for item in item {
|
||||||
|
#write
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter_map(|x| x)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
&#name::#label{..} => {
|
||||||
|
#enum_fields
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|x| x.is_some())
|
.filter(|x| x.is_some())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user