Skip to content

Deserializer does not respect the "hints" from the deserialize_xxx functions #1253

@TroyKomodo

Description

@TroyKomodo

According to the documentation on the functions,

/// Hint that the `Deserialize` type is expecting a string value and does
/// not benefit from taking ownership of buffered data owned by the
/// `Deserializer`.
///
/// If the `Visitor` would benefit from taking ownership of `String` data,
/// indicate this to the `Deserializer` by using `deserialize_string`
/// instead.
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
    V: Visitor<'de>;

The deserializer should take a "hint" that the type is a string. To me this reads as, we should try convert our input into a string if its not a string, otherwise if thats not possible give the visitor whatever we have.

This is then further implied by the Visitor traits all having default impls for every method that just return an error based on the expected impl.

However serde_json::Deserializer does not follow this behavior.

json/src/de.rs

Lines 1533 to 1543 in 8a56cfa

let value = match peek {
b'"' => {
self.eat_char();
self.scratch.clear();
match tri!(self.read.parse_str(&mut self.scratch)) {
Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
Reference::Copied(s) => visitor.visit_str(s),
}
}
_ => Err(self.peek_invalid_type(&visitor)),
};

Instead serde_json returns a hard error with out invoking the visitor and letting the visitor handle values it didnt expect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions