serde-rs / serde

Serialization framework for Rust
https://serde.rs/
Apache License 2.0
8.81k stars 747 forks source link

internally tagged newtype variant containing unit struct fails to deserialize when extra keys exist #2755

Open PookieBuns opened 3 weeks ago

PookieBuns commented 3 weeks ago

Thanks to https://github.com/serde-rs/serde/pull/1085, internally tagged unit structs are able to be deserialized properly.

However, this only works if the only key in the input is the tag name. If any other key exists, the serialization will fail. This issue does not occur when the newtype variant is an empty struct.

Code to reproduce

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct MyStruct1 {}

#[derive(Serialize, Deserialize, Debug)]
struct MyStruct2;

#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "variant")]
enum MyEnum {
    A(MyStruct1),
    B(MyStruct2),
}

fn main() {
    let only_tag_json = r#"{"variant":"A"}"#;
    let this_works: MyEnum = serde_json::from_str(only_tag_json).unwrap();
    println!("{this_works:#?}");
    let with_extra_keys_json_a = r#"{"variant":"A", "k":"v"}"#;
    let this_also_works: MyEnum = serde_json::from_str(with_extra_keys_json_a).unwrap();
    println!("{this_also_works:#?}");
    let with_extra_keys_json_b = r#"{"variant":"B", "k":"v"}"#;
    let this_doesnt_work: MyEnum = serde_json::from_str(with_extra_keys_json_b).unwrap();
    println!("{this_doesnt_work:#?}");
}

Ideally, the unit struct should also be able to ignore the extra key when serializing and succeed, since all information is known to serialize properly