Deserialize flatten map with ignored fields

How to deserialize such a structure in serde?

    let json = r#"{
        "address-cells":1,
        "cpus":{
            "string-param":"string",
            "other-ignored-param":123,
            "cpu@0":{"compatible":"my-uarch"},
            "cpu@1":{"compatible":"my-uarch"}
        }
    }"#;

It would be nice to use #[serde(flatten)] on a BTreeMap etc., but serde can't decide whether the field is a cpu structure or a conventional parameter. The error shows:

thread 'main' panicked at 'called Result::unwrap() on an Err value: Error("invalid type: integer 123, expected struct Cpu", line: 8, column: 9)', src/main.rs:37:49

Playground link: Rust Playground

Serde lets you use enums as value so that the variant is automatically recognized.

https://serde.rs/enum-representations.html#untagged

1 Like

Thanks! My problem solved. Here's the code: Rust Playground

1 Like

Another option would be to create a custom deserialization function for the cpu field. It could filter for the "cpu@" prefix which you show in your example. It then only flattens those entries with the prefix and ignores other values by deserializing them into IgnoredAny.

The code below does a bit too much. It strips the "cpu@" prefix and prevents the key from being borrowed. But it should give you an idea how everything would work together.

serde_with::with_prefix!(prefix_cpu "cpu@");

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
struct Tree<'a> {
    #[serde(rename = "address-cells")]
    num_address_cells: u32,
    #[serde(borrow)]
    cpus: Cpus<'a>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
struct Cpus<'a> {
    string_param: &'a str,
    #[serde(flatten, borrow, with="prefix_cpu")]
    cpu: BTreeMap<String, Cpu<'a>>,
}

#[derive(Debug, Serialize, Deserialize)]
struct Cpu<'a> {
    compatible: &'a str,
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.