Open
Description
It looks like nested untagged enums can be deserialized to the wrong variant. In the repro below, this only occurs if the number of fields in StructWithStrings
matches the number of entries in Foo:Arry
's vector (tested for n=1..5). If a second string entry is added to the Foo::Array
object or if another field is added to StructWithString
, the assert doesn't trigger.
use serde::{Deserialize, Serialize};
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct StructWithStrings {
pub field1: String,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ScalarData {
String(String),
LanguageString(StructWithStrings),
}
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Foo {
Scalar(ScalarData),
Array(Vec<ScalarData>),
}
fn main() {
let val = Foo::Array(
vec![
ScalarData::String("String 1".to_string()),
]
);
println!("Val: {val:#?}");
let json_val = serde_json::to_string_pretty(&val).unwrap();
println!("JSON: {json_val}");
let val_again: Foo = serde_json::from_str(&json_val).unwrap();
println!("Val again: {val_again:#?}");
assert_eq!(val, val_again);
}
Output
> cargo run
Compiling serde_repro v0.1.0 (/home/lillis/projects/serde_repro)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s
Running `target/debug/serde_repro`
Val: Array(
[
String(
"String 1",
),
],
)
JSON: [
"String 1"
]
Val again: Scalar(
LanguageString(
StructWithStrings {
field1: "String 1",
},
),
)
thread 'main' panicked at src/main.rs:38:5:
assertion `left == right` failed
left: Array([String("String 1")])
right: Scalar(LanguageString(StructWithStrings { field1: "String 1" }))
I've also put the repro in a separate repo here: https://github.com/WillLillis/serde_json_repro. I originally ran into this while working with lsp-types's Hover
struct. Thanks so much for this amazing project!
Metadata
Metadata
Assignees
Labels
No labels