diff --git a/yaserde/tests/deserializer.rs b/yaserde/tests/deserializer.rs index 0035fe7..fd06f20 100644 --- a/yaserde/tests/deserializer.rs +++ b/yaserde/tests/deserializer.rs @@ -887,3 +887,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, + } + + #[derive(Default, PartialEq, Debug, YaDeserialize)] + pub struct Struct { + sub: SubStruct, + } + + convert_and_validate!("", Struct, Struct::default()); + + convert_and_validate!( + "42", + 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, + } + + #[derive(Default, PartialEq, Debug, YaDeserialize)] + pub struct Struct { + sub: SubStruct, + } + + convert_and_validate!("", Struct, Struct::default()); + + convert_and_validate!( + "42", + Struct, + Struct { + sub: SubStruct { + sub: Some(SubSubStruct { sub: 42 }) + } + } + ); +} diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 6e21064..6e9b66d 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -179,9 +179,15 @@ pub fn parse( let visit_struct = |struct_name: syn::Path, action: TokenStream| { Some(quote! { #label_name => { - let value = #struct_name::deserialize(reader)?; - #value_label #action; - let _root = reader.next_event(); + if depth == 0 { + // Don't count current struct's StartElement as substruct's StartElement + 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; + } } }) }; @@ -503,8 +509,10 @@ fn build_call_visitor( } let result = reader.read_inner_value::<#field_type, _>(|reader| { - if let Ok(XmlEvent::Characters(s)) = reader.next_event() { - visitor.#visitor(&s) + if let Ok(XmlEvent::Characters(s)) = reader.peek() { + let val = visitor.#visitor(&s); + let _event = reader.next_event()?; + val } else { Err(format!("unable to parse content for {}", #label_name)) }