dtolnay / serde-yaml

Strongly typed YAML library for Rust
Apache License 2.0
964 stars 164 forks source link

[BUG] `#[serde(flatten)]` on `HashMap<T, _>` causes deserialisation failure unless `T` is `String` #351

Open cyqsimon opened 1 year ago

cyqsimon commented 1 year ago

MRE:

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Serialize, Deserialize)]
struct Foo {
    #[serde(flatten)]
    bar: HashMap<usize, bool>,
}

fn main() {
    let foo = Foo {
        bar: [(69, true), (420, false)].into_iter().collect(),
    };

    // serialisation is fine
    let foo_yaml = serde_yaml::to_string(&foo).unwrap();
    println!("{foo_yaml}");

    // this errors: "invalid type: string \"420\", expected usize"
    let foo_roundtrip: Foo = serde_yaml::from_str(&foo_yaml).unwrap();
    dbg!(&foo_roundtrip);
}

In this example, if you change the type of bar to HashMap<String, bool>, the error goes away.

I read https://serde.rs/attr-flatten.html and didn't see any mention of using usize as key being illegal, so I assumed it's a bug.


I'm not sure what to make of this issue. Maybe there was an assumption made that map keys must be strings?

Also, this may be related to #344, maybe not.