Basic support for enum attribute serialization
This commit is contained in:
parent
53d3a85088
commit
2f8e87cd88
@ -147,6 +147,49 @@ fn attribute_enum() {
|
|||||||
deserialize_and_validate!(content, model, XmlStruct);
|
deserialize_and_validate!(content, model, XmlStruct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn attribute_enum2() {
|
||||||
|
#[derive(YaSerialize)]
|
||||||
|
#[yaserde(rename = "child1")]
|
||||||
|
struct Child1 {
|
||||||
|
#[yaserde(attribute, rename = "val")]
|
||||||
|
pub val: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize)]
|
||||||
|
#[yaserde(rename = "child2")]
|
||||||
|
struct Child2 {
|
||||||
|
#[yaserde(attribute)]
|
||||||
|
pub num: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(YaSerialize)]
|
||||||
|
#[yaserde(flatten)]
|
||||||
|
enum Base {
|
||||||
|
#[yaserde(flatten)]
|
||||||
|
C1(Child1),
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = r#"<child1 val="hello world" />"#;
|
||||||
|
let model = Base::C1(Child1 {
|
||||||
|
val: "hello world".into(),
|
||||||
|
});
|
||||||
|
serialize_and_validate!(model, content);
|
||||||
|
|
||||||
|
#[derive(YaSerialize)]
|
||||||
|
#[yaserde(rename = "base")]
|
||||||
|
enum Base2 {
|
||||||
|
#[yaserde(flatten)]
|
||||||
|
C1(Child1),
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = r#"<base><child1 val="hello world" /></base>"#;
|
||||||
|
let model = Base2::C1(Child1 {
|
||||||
|
val: "hello world".into(),
|
||||||
|
});
|
||||||
|
serialize_and_validate!(model, content);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unnamed_enum() {
|
fn unnamed_enum() {
|
||||||
#[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
|
#[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
|
||||||
|
|||||||
@ -14,11 +14,81 @@ pub fn serialize(
|
|||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let inner_enum_inspector = inner_enum_inspector(data_enum, name, root_attributes);
|
let inner_enum_inspector = inner_enum_inspector(data_enum, name, root_attributes);
|
||||||
|
|
||||||
|
let get_id = |field: &YaSerdeField| {
|
||||||
|
field
|
||||||
|
.label()
|
||||||
|
.unwrap_or(field.get_type().get_simple_type_visitor())
|
||||||
|
};
|
||||||
|
|
||||||
|
let variant_matches: TokenStream = data_enum
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.map(|variant| -> TokenStream {
|
||||||
|
let _attrs = crate::common::YaSerdeAttribute::parse(&variant.attrs);
|
||||||
|
|
||||||
|
let all_fields = variant
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| YaSerdeField::new(field.clone()));
|
||||||
|
|
||||||
|
let attribute_fields: Vec<_> = all_fields
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|field| {
|
||||||
|
field.is_attribute()
|
||||||
|
|| (field.is_flatten() && matches!(field.get_type(), Field::FieldStruct { .. }))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
attribute_fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| {
|
||||||
|
let label = variant.ident.clone();
|
||||||
|
let var = get_id(field);
|
||||||
|
let name = name.clone();
|
||||||
|
|
||||||
|
let destructure = if field.get_value_label().is_some() {
|
||||||
|
quote! {{#var, ..}}
|
||||||
|
} else {
|
||||||
|
quote! {(#var, ..)}
|
||||||
|
};
|
||||||
|
|
||||||
|
if field.is_attribute() {
|
||||||
|
quote! { #name::#label { .. } => { }, }
|
||||||
|
} else {
|
||||||
|
match field.get_type() {
|
||||||
|
Field::FieldStruct { .. } => {
|
||||||
|
if root_attributes.flatten {
|
||||||
|
quote! {
|
||||||
|
match self {
|
||||||
|
#name::#label #destructure => {
|
||||||
|
let (attributes, namespace) = #var.serialize_attributes(
|
||||||
|
child_attributes,
|
||||||
|
child_attributes_namespace,
|
||||||
|
)?;
|
||||||
|
child_attributes_namespace.extend(&namespace);
|
||||||
|
child_attributes.extend(attributes);
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => quote! { #name::#label { .. } => { },},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
implement_serializer(
|
implement_serializer(
|
||||||
name,
|
name,
|
||||||
root,
|
root,
|
||||||
root_attributes,
|
root_attributes,
|
||||||
quote!(),
|
quote!(#variant_matches),
|
||||||
quote!(match self {
|
quote!(match self {
|
||||||
#inner_enum_inspector
|
#inner_enum_inspector
|
||||||
}),
|
}),
|
||||||
@ -205,7 +275,13 @@ fn inner_enum_inspector(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Field::FieldStruct { .. } => write_element(&match_field(&serialize)),
|
Field::FieldStruct { .. } => {
|
||||||
|
if variant_attrs.flatten || field.is_flatten() {
|
||||||
|
match_field("e!{ ::yaserde::YaSerialize::serialize(item, writer)?})
|
||||||
|
} else {
|
||||||
|
write_element(&match_field(&serialize))
|
||||||
|
}
|
||||||
|
}
|
||||||
Field::FieldString => match_field(&write_element(&write_string_chars)),
|
Field::FieldString => match_field(&write_element(&write_string_chars)),
|
||||||
_simple_type => match_field(&write_simple_type),
|
_simple_type => match_field(&write_simple_type),
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user