json icon indicating copy to clipboard operation
json copied to clipboard

Error deserializing tagged enum containing map with integer keys

Open manforowicz opened this issue 8 months ago • 1 comments

I get a runtime error when trying to deserialize a tagged enum that contains a map with integer keys. Here's a reproducible example:

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

#[derive(Serialize, Deserialize)]
#[serde(tag = "type")]
enum Msg {
    Map { map: BTreeMap<i32, i32> },
}

fn main() {
    let msg = Msg::Map {
        map: [(1, 2), (3, 4)].into(),
    };

    let serialized = serde_json::to_string_pretty(&msg).unwrap();
    println!("Serialized:\n{serialized}");

    let _received: Msg = serde_json::from_str(&serialized).unwrap();
}

It panics with:

Error("invalid type: string \"1\", expected i32", line: 0, column: 0)

Playground link.

However, I don't get an error when I remove the #[serde(tag = "type")], or when I use non-integer keys. Is this expected behavior?

manforowicz avatar Apr 21 '25 21:04 manforowicz

I think this is due to using TaggedContentVisitor from serde-core which didn't specially handle the json map key's type mismatch case,(serde json can deser from raw string because it special handle in that path) maybe a quick fix would be impl serde json's own TaggedContentVisitor which handle map key's type conversion?

discord9 avatar Oct 15 '25 12:10 discord9