Merge branch 'master' of github.com:media-io/yaserde into fix_default_namespace_prefix
This commit is contained in:
commit
2c632fe0ee
@ -18,7 +18,6 @@ pub struct Deserializer<R: Read> {
|
|||||||
depth: usize,
|
depth: usize,
|
||||||
reader: EventReader<R>,
|
reader: EventReader<R>,
|
||||||
peeked: Option<XmlEvent>,
|
peeked: Option<XmlEvent>,
|
||||||
is_map_value: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, R: Read> Deserializer<R> {
|
impl<'de, R: Read> Deserializer<R> {
|
||||||
@ -27,7 +26,6 @@ impl<'de, R: Read> Deserializer<R> {
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
reader,
|
reader,
|
||||||
peeked: None,
|
peeked: None,
|
||||||
is_map_value: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,28 +103,16 @@ impl<'de, R: Read> Deserializer<R> {
|
|||||||
self.depth
|
self.depth
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_map_value(&mut self) {
|
|
||||||
self.is_map_value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unset_map_value(&mut self) -> bool {
|
|
||||||
::std::mem::replace(&mut self.is_map_value, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_inner_value<T, F: FnOnce(&mut Self) -> Result<T, String>>(
|
pub fn read_inner_value<T, F: FnOnce(&mut Self) -> Result<T, String>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Result<T, String> {
|
) -> Result<T, String> {
|
||||||
if self.unset_map_value() {
|
if let Ok(XmlEvent::StartElement { name, .. }) = self.next_event() {
|
||||||
if let Ok(XmlEvent::StartElement { name, .. }) = self.next_event() {
|
let result = f(self)?;
|
||||||
let result = f(self)?;
|
self.expect_end_element(&name)?;
|
||||||
self.expect_end_element(&name)?;
|
Ok(result)
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
Err("Internal error: Bad Event".to_string())
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
f(self)
|
Err("Internal error: Bad Event".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -883,3 +883,56 @@ fn de_subitem_issue_12_attributes_with_sub() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn de_same_field_name_sub() {
|
||||||
|
#[derive(Default, PartialEq, Debug, YaDeserialize)]
|
||||||
|
pub struct SubStruct {
|
||||||
|
sub: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, PartialEq, Debug, YaDeserialize)]
|
||||||
|
pub struct Struct {
|
||||||
|
sub: SubStruct,
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_and_validate!("<Struct><sub /></Struct>", Struct, Struct::default());
|
||||||
|
|
||||||
|
convert_and_validate!(
|
||||||
|
"<Struct><sub><sub>42</sub></sub></Struct>",
|
||||||
|
Struct,
|
||||||
|
Struct {
|
||||||
|
sub: SubStruct { sub: Some(42) }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn de_same_field_name_sub_sub() {
|
||||||
|
#[derive(Default, PartialEq, Debug, YaDeserialize)]
|
||||||
|
pub struct SubSubStruct {
|
||||||
|
sub: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, PartialEq, Debug, YaDeserialize)]
|
||||||
|
pub struct SubStruct {
|
||||||
|
sub: Option<SubSubStruct>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, PartialEq, Debug, YaDeserialize)]
|
||||||
|
pub struct Struct {
|
||||||
|
sub: SubStruct,
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_and_validate!("<Struct><sub /></Struct>", Struct, Struct::default());
|
||||||
|
|
||||||
|
convert_and_validate!(
|
||||||
|
"<Struct><sub><sub><sub>42</sub></sub></sub></Struct>",
|
||||||
|
Struct,
|
||||||
|
Struct {
|
||||||
|
sub: SubStruct {
|
||||||
|
sub: Some(SubSubStruct { sub: 42 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -214,18 +214,15 @@ fn build_unnamed_visitor_calls(
|
|||||||
Some(quote! {
|
Some(quote! {
|
||||||
let visitor = #visitor_label{};
|
let visitor = #visitor_label{};
|
||||||
|
|
||||||
if let XmlEvent::StartElement {name, ..} = reader.peek()?.clone() {
|
if let Some(namespace) = name.namespace.as_ref() {
|
||||||
if let Some(namespace) = name.namespace {
|
match namespace.as_str() {
|
||||||
match namespace.as_str() {
|
bad_ns => {
|
||||||
bad_ns => {
|
let msg = format!("bad field namespace for {}, found {}",
|
||||||
let msg = format!("bad field namespace for {}, found {}",
|
name.local_name.as_str(),
|
||||||
name.local_name.as_str(),
|
bad_ns);
|
||||||
bad_ns);
|
return Err(msg);
|
||||||
return Err(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.set_map_value()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = reader.read_inner_value::<#field_type, _>(|reader| {
|
let result = reader.read_inner_value::<#field_type, _>(|reader| {
|
||||||
@ -248,7 +245,6 @@ fn build_unnamed_visitor_calls(
|
|||||||
|
|
||||||
let call_struct_visitor = |struct_name, action| {
|
let call_struct_visitor = |struct_name, action| {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
reader.set_map_value();
|
|
||||||
match #struct_name::deserialize(reader) {
|
match #struct_name::deserialize(reader) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
#action;
|
#action;
|
||||||
|
|||||||
@ -179,10 +179,15 @@ pub fn parse(
|
|||||||
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
#label_name => {
|
#label_name => {
|
||||||
reader.set_map_value();
|
if depth == 0 {
|
||||||
let value = #struct_name::deserialize(reader)?;
|
// Don't count current struct's StartElement as substruct's StartElement
|
||||||
#value_label #action;
|
let _root = reader.next_event();
|
||||||
let _root = reader.next_event();
|
}
|
||||||
|
if let Ok(XmlEvent::StartElement { .. }) = reader.peek() {
|
||||||
|
// If substruct's start element found then deserialize substruct
|
||||||
|
let value = #struct_name::deserialize(reader)?;
|
||||||
|
#value_label #action;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -493,26 +498,21 @@ fn build_call_visitor(
|
|||||||
#label_name => {
|
#label_name => {
|
||||||
let visitor = #visitor_label{};
|
let visitor = #visitor_label{};
|
||||||
|
|
||||||
if let XmlEvent::StartElement {name, ..} = reader.peek()?.clone() {
|
if let Some(namespace) = name.namespace.as_ref() {
|
||||||
if let Some(namespace) = name.namespace {
|
match namespace.as_str() {
|
||||||
match namespace.as_str() {
|
#namespaces_matches
|
||||||
#namespaces_matches
|
bad_ns => {
|
||||||
bad_ns => {
|
let msg = format!("bad field namespace for {}, found {}", name.local_name.as_str(), bad_ns);
|
||||||
let msg = format!("bad field namespace for {}, found {}", name.local_name.as_str(), bad_ns);
|
return Err(msg);
|
||||||
return Err(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.set_map_value()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = reader.read_inner_value::<#field_type, _>(|reader| {
|
let result = reader.read_inner_value::<#field_type, _>(|reader| {
|
||||||
if let XmlEvent::EndElement { .. } = *reader.peek()? {
|
if let Ok(XmlEvent::Characters(s)) = reader.peek() {
|
||||||
return visitor.#visitor("");
|
let val = visitor.#visitor(&s);
|
||||||
}
|
let _event = reader.next_event()?;
|
||||||
|
val
|
||||||
if let Ok(XmlEvent::Characters(s)) = reader.next_event() {
|
|
||||||
visitor.#visitor(&s)
|
|
||||||
} else {
|
} else {
|
||||||
Err(format!("unable to parse content for {}", #label_name))
|
Err(format!("unable to parse content for {}", #label_name))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user