Skip to content

Deserializing to a flattened struct calls deserialize_map, but deserializing to an already-flat struct does not #1529

@peterjoel

Description

@peterjoel

The original problem is that my format is not completely self-describing because it does not encode field types, and I need to rely on the types to be inferred from the target struct when deserializing. However, I found that deserialize_any was being called on my Deserializer when I used the #[serde(flatten)] attribute.

I have tried to reduce this problem to the minimal necessary code, in this gist. The problem shows itself by the fact that deserialize_map is called in the failing test, but is not called in the passing test.

Deserializing to this struct works (does not call deserialize_map):

#[derive(Deserialize)]
#[serde(rename = "Message")]
struct Flattened {
    a: String,
    b: String,
}

But deserializing these to structs results in a call to deserialize_map:

#[derive(Deserialize)]
#[serde(rename = "Message")]
struct Nested {
    a: String,
    #[serde(flatten)]
    inner: NestedInner,
}

#[derive(Debug, PartialEq, Deserialize)]
struct NestedInner {
    b: String,
}

I also checked that both structures expect the following deserialize tokens:

&[
    Token::Struct { name: "Message", len: 5 },
    Token::Str("a"),
    Token::Str("v1"),
    Token::Str("b"),
    Token::Str("99"),
    Token::StructEnd,
]

Perhaps I have this wrong, but I would expect this to indicate that both visitors should interact with the deserializer identically.

Full code: https://gist.github.com/peterjoel/a41363fea48c4cb529e4a4bf8421ec20

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