Support deserializing xst xs:list attributes as Vec types.
This commit is contained in:
parent
40dcff31e7
commit
9c5b993c84
@ -4,8 +4,10 @@ extern crate yaserde;
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use log::debug;
|
||||
use std::default;
|
||||
use std::io::Read;
|
||||
use yaserde::de::from_str;
|
||||
use std::str::FromStr;
|
||||
use yaserde::de::{self, from_str};
|
||||
use yaserde::YaDeserialize;
|
||||
|
||||
fn init() {
|
||||
@ -1050,3 +1052,37 @@ fn de_same_field_name_but_some_other_fields_or_something() {
|
||||
serialize_and_validate!(model, content);
|
||||
deserialize_and_validate!(content, model, FooOuter);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn de_attribute_sequence() {
|
||||
init();
|
||||
|
||||
#[derive(Default, Debug, YaDeserialize, PartialEq)]
|
||||
pub enum Inner {
|
||||
#[default]
|
||||
#[yaserde(rename = "foo")]
|
||||
Foo,
|
||||
#[yaserde(rename = "bar")]
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, YaDeserialize)]
|
||||
pub struct Outer {
|
||||
#[yaserde(attribute, rename = "seq1")]
|
||||
seq1: Vec<i32>,
|
||||
#[yaserde(child, attribute, rename = "seq2")]
|
||||
seq2: Vec<Inner>,
|
||||
#[yaserde(attribute, rename = "seq3")]
|
||||
seq3: Vec<String>,
|
||||
}
|
||||
|
||||
let content = r#"<Outer seq1="1 2 3 4" seq2="foo foo bar" seq3="one two" />"#;
|
||||
let model = Outer {
|
||||
seq1: vec![1, 2, 3, 4],
|
||||
seq2: vec![Inner::Foo, Inner::Foo, Inner::Bar],
|
||||
seq3: vec!["one".to_string(), "two".to_string()],
|
||||
};
|
||||
|
||||
//serialize_and_validate!(model, content);
|
||||
deserialize_and_validate!(content, model, Outer);
|
||||
}
|
||||
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(
|
||||
"e! { .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(
|
||||
"e! { .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 }),
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user