diff --git a/yaserde/src/de/mod.rs b/yaserde/src/de/mod.rs index 11f44b5..a894d28 100644 --- a/yaserde/src/de/mod.rs +++ b/yaserde/src/de/mod.rs @@ -18,7 +18,6 @@ pub struct Deserializer { depth: usize, reader: EventReader, peeked: Option, - is_map_value: bool, } impl<'de, R: Read> Deserializer { @@ -27,7 +26,6 @@ impl<'de, R: Read> Deserializer { depth: 0, reader, peeked: None, - is_map_value: false, } } @@ -105,28 +103,16 @@ impl<'de, R: Read> Deserializer { 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 Result>( &mut self, f: F, ) -> Result { - if self.unset_map_value() { - if let Ok(XmlEvent::StartElement { name, .. }) = self.next_event() { - let result = f(self)?; - self.expect_end_element(&name)?; - Ok(result) - } else { - Err("Internal error: Bad Event".to_string()) - } + if let Ok(XmlEvent::StartElement { name, .. }) = self.next_event() { + let result = f(self)?; + self.expect_end_element(&name)?; + Ok(result) } else { - f(self) + Err("Internal error: Bad Event".to_string()) } } diff --git a/yaserde/tests/deserializer.rs b/yaserde/tests/deserializer.rs index bd5474a..21df4c0 100644 --- a/yaserde/tests/deserializer.rs +++ b/yaserde/tests/deserializer.rs @@ -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, + } + + #[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_enum.rs b/yaserde_derive/src/de/expand_enum.rs index fd17e12..4fdb0ed 100644 --- a/yaserde_derive/src/de/expand_enum.rs +++ b/yaserde_derive/src/de/expand_enum.rs @@ -214,18 +214,15 @@ fn build_unnamed_visitor_calls( Some(quote! { let visitor = #visitor_label{}; - if let XmlEvent::StartElement {name, ..} = reader.peek()?.clone() { - if let Some(namespace) = name.namespace { - match namespace.as_str() { - bad_ns => { - let msg = format!("bad field namespace for {}, found {}", - name.local_name.as_str(), - bad_ns); - return Err(msg); - } + if let Some(namespace) = name.namespace.as_ref() { + match namespace.as_str() { + bad_ns => { + let msg = format!("bad field namespace for {}, found {}", + name.local_name.as_str(), + bad_ns); + return Err(msg); } } - reader.set_map_value() } 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| { Some(quote! { - reader.set_map_value(); match #struct_name::deserialize(reader) { Ok(value) => { #action; diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 842c3de..1f1d51e 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -179,10 +179,15 @@ pub fn parse( let visit_struct = |struct_name: syn::Path, action: TokenStream| { Some(quote! { #label_name => { - reader.set_map_value(); - 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; + } } }) }; @@ -493,26 +498,21 @@ fn build_call_visitor( #label_name => { let visitor = #visitor_label{}; - if let XmlEvent::StartElement {name, ..} = reader.peek()?.clone() { - if let Some(namespace) = name.namespace { - match namespace.as_str() { - #namespaces_matches - bad_ns => { - let msg = format!("bad field namespace for {}, found {}", name.local_name.as_str(), bad_ns); - return Err(msg); - } + if let Some(namespace) = name.namespace.as_ref() { + match namespace.as_str() { + #namespaces_matches + bad_ns => { + let msg = format!("bad field namespace for {}, found {}", name.local_name.as_str(), bad_ns); + return Err(msg); } } - reader.set_map_value() } let result = reader.read_inner_value::<#field_type, _>(|reader| { - if let XmlEvent::EndElement { .. } = *reader.peek()? { - return visitor.#visitor(""); - } - - 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)) }