diff --git a/src/de/mod.rs b/src/de/mod.rs index 8e6c6c86..90a104e0 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -2821,7 +2821,13 @@ where // SAFETY: The reader is guaranteed that we don't have unmatched tags // If we here, then out deserializer has a bug DeEvent::End(e) => unreachable!("{:?}", e), - DeEvent::Text(_) => Err(DeError::ExpectedStart), + // Deserializer methods are only hints, if deserializer could not satisfy + // request, it should return the data that it has. It is responsibility + // of a Visitor to return an error if it does not understand the data + DeEvent::Text(e) => match e.text { + Cow::Borrowed(s) => visitor.visit_borrowed_str(s), + Cow::Owned(s) => visitor.visit_string(s), + }, DeEvent::Eof => Err(DeError::UnexpectedEof), } } diff --git a/src/de/text.rs b/src/de/text.rs index 4c3b66da..f3129e48 100644 --- a/src/de/text.rs +++ b/src/de/text.rs @@ -32,7 +32,9 @@ use std::borrow::Cow; /// deserializer; /// - sequences, tuples and tuple structs are deserialized using [`SimpleTypeDeserializer`] /// (this is the difference): text content passed to the deserializer directly; -/// - structs and maps returns [`DeError::ExpectedStart`]; +/// - structs and maps calls [`Visitor::visit_borrowed_str`] or [`Visitor::visit_string`], +/// it is responsibility of the type to return an error if it do not able to process +/// this data; /// - enums: /// - the variant name is deserialized as `$text`; /// - the content is deserialized using the same deserializer: @@ -117,12 +119,15 @@ impl<'de> Deserializer<'de> for TextDeserializer<'de> { self, _name: &'static str, _fields: &'static [&'static str], - _visitor: V, + visitor: V, ) -> Result where V: Visitor<'de>, { - Err(DeError::ExpectedStart) + // Deserializer methods are only hints, if deserializer could not satisfy + // request, it should return the data that it has. It is responsibility + // of a Visitor to return an error if it does not understand the data + self.deserialize_str(visitor) } fn deserialize_enum( diff --git a/src/errors.rs b/src/errors.rs index 057dc618..1142892f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -205,12 +205,6 @@ pub mod serialize { /// [`Event::Start`]: crate::events::Event::Start /// [`Event::End`]: crate::events::Event::End UnexpectedEof, - /// This error indicates that [`deserialize_struct`] was called, but there - /// is no any XML element in the input. That means that you try to deserialize - /// a struct not from an XML element. - /// - /// [`deserialize_struct`]: serde::de::Deserializer::deserialize_struct - ExpectedStart, /// An attempt to deserialize to a type, that is not supported by the XML /// store at current position, for example, attempt to deserialize `struct` /// from attribute or attempt to deserialize binary data. @@ -245,7 +239,6 @@ pub mod serialize { f.write_str(")`") } DeError::UnexpectedEof => write!(f, "Unexpected `Event::Eof`"), - DeError::ExpectedStart => write!(f, "Expecting `Event::Start`"), DeError::Unsupported(s) => write!(f, "Unsupported operation: {}", s), #[cfg(feature = "overlapped-lists")] DeError::TooManyEvents(s) => write!(f, "Deserializer buffers {} events, limit exceeded", s), diff --git a/tests/serde-de.rs b/tests/serde-de.rs index b72ef43d..59f30172 100644 --- a/tests/serde-de.rs +++ b/tests/serde-de.rs @@ -890,8 +890,14 @@ mod struct_ { match from_str::( "\nexcess text\t42answer", ) { - Err(DeError::ExpectedStart) => {} - x => panic!("Expected `Err(ExpectedStart)`, but got `{:?}`", x), + Err(DeError::Custom(reason)) => assert_eq!( + reason, + "invalid type: string \"excess text\", expected struct Elements", + ), + x => panic!( + r#"Expected `Err(Custom("invalid type: string \"excess text\", expected struct Elements"))`, but got `{:?}`"#, + x + ), }; } @@ -901,8 +907,14 @@ mod struct_ { match from_str::( "42answer", ) { - Err(DeError::ExpectedStart) => {} - x => panic!("Expected `Err(ExpectedStart)`, but got `{:?}`", x), + Err(DeError::Custom(reason)) => assert_eq!( + reason, + "invalid type: string \"excess cdata\", expected struct Elements", + ), + x => panic!( + r#"Expected `Err(Custom("invalid type: string \"excess cdata\", expected struct Elements"))`, but got `{:?}`"#, + x + ), }; }