json
json copied to clipboard
Deserializing (tagged) Tuple Variant with no elements inside untagged enum results in error
Hi!
If you have an enum such as
#[serde(untagged)]
enum TestBackwardCompatible {
Test(Test)
}
enum Test {
Empty()
}
It will serialize to {"Empty":[]} but deserialization will fail with data did not match any variant of untagged enum TestBackwardCompatible.
Some example code (playground):
use serde_derive::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum TestBackwardCompatible {
Test(Test),
}
#[derive(Serialize, Deserialize, Debug)]
enum Test {
Empty(),
SingleElement(u8),
MultiElement(u8, u8),
ZeroElementArray([u8; 0]), // This is an workaround with expected behaviour
}
fn main() {
// Some examples of what does not fail
let text = serde_json::to_string(&TestBackwardCompatible::Test(Test::SingleElement(10))).unwrap();
println!("{}", text);
let data: TestBackwardCompatible = serde_json::from_str(&text).unwrap();
println!("{:?}\n", data);
let text = serde_json::to_string(&TestBackwardCompatible::Test(Test::MultiElement(10, 20))).unwrap();
println!("{}", text);
let data: TestBackwardCompatible = serde_json::from_str(&text).unwrap();
println!("{:?}\n", data);
let text = serde_json::to_string(&TestBackwardCompatible::Test(Test::ZeroElementArray([]))).unwrap();
println!("{}", text);
let data: TestBackwardCompatible = serde_json::from_str(&text).unwrap();
println!("{:?}\n", data);
// The problem lies here
let text = serde_json::to_string(&TestBackwardCompatible::Test(Test::Empty())).unwrap();
println!("{}", text);
// Deserializing the variant directly works fine
let data: Test = serde_json::from_str(&text).unwrap();
println!("deserializing directly works: {:?}", data);
// Deserializing it inside the untagged enum fails
let data: TestBackwardCompatible = serde_json::from_str(&text).unwrap(); // panics!
println!("this won't ever find its way to stdout: {:?}", data);
}
Possibly related to https://github.com/serde-rs/serde/issues/1183