Support deserializing xst xs:list attributes as Vec types.

This commit is contained in:
John Hughes
2023-12-23 21:46:27 +01:00
parent 40dcff31e7
commit 9c5b993c84
3 changed files with 66 additions and 3 deletions

View File

@@ -293,6 +293,7 @@ impl From<&Field> for String {
Field::FieldU64 => "u64".to_string(),
Field::FieldF32 => "f32".to_string(),
Field::FieldF64 => "f64".to_string(),
Field::FieldStruct { struct_name } => quote!{#struct_name}.to_string(),
_ => panic!("Not a simple type: {:?}", field),
}
}

View File

@@ -38,7 +38,7 @@ pub fn parse(
quote!(::std::vec![]),
),
Field::FieldOption { .. } | Field::FieldVec { .. } => {
unimplemented!();
unimplemented!("Option or Vec nested in Vec<>");
}
simple_type => {
let type_token: TokenStream = simple_type.into();
@@ -239,6 +239,20 @@ pub fn parse(
})
};
let visit_vec = |action: &TokenStream, visitor: &Ident, visitor_label: &Ident| {
Some(quote! {
for attr in attributes {
if attr.name.local_name == #label_name {
for value in attr.value.split_whitespace() {
let visitor = #visitor_label{};
let value = visitor.#visitor(value)?;
#label #action;
}
}
}
})
};
let visit_string = || {
Some(quote! {
for attr in attributes {
@@ -276,7 +290,19 @@ pub fn parse(
Field::FieldOption { data_type } => {
visit_sub(data_type, quote! { = ::std::option::Option::Some(value) })
}
Field::FieldVec { .. } => unimplemented!(),
Field::FieldVec { data_type } => match data_type.as_ref() {
Field::FieldStruct { struct_name } => visit_vec(
&quote! { .push(value) },
&Ident::new("visit_str", field.get_span()),
&build_visitor_ident(&label_name, field.get_span(), Some(&struct_name)),
),
Field::FieldOption { .. } | Field::FieldVec { .. } => unimplemented!("Not supported"),
simple_type => visit_vec(
&quote! { .push(value) },
&simple_type.get_simple_type_visitor(),
&visitor_label,
),
},
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }),
simple_type => visit_simple(simple_type, quote! { = value }),
}