有没有办法在 Rust 中为(反)序列化 "flatten" 枚举?

Is there a way to "flatten" enums for (de)serialization in Rust?

我有一个由其他枚举组成的枚举,类似于下面的(serde派生和为简洁起见省略注释):

enum Main {
    A(SubA),
    B(SubB),
}

enum SubA { X1, X2, X3 }
enum SubB { Y1, Y2, Y3 }

我希望能够使用 serde 反序列化 "X1" 或 "Y3" 等字符串,并自动取回 Main::A(SubA::X1)Main::B(SubB::Y3),分别.

我知道 serde 支持新类型结构上的 #[serde(transparent)] 属性,这符合我的喜好。但是,它似乎只适用于结构或枚举级别,而不适用于枚举变量级别。有没有一种方法可以自动获得我正在寻找的行为?我可以确保任何包含的子枚举中的任何变体名称都不会重叠。

除了希望保持 Rust 2018 稳定版之外,我对我的项目没有其他限制,并且我愿意接受任何有帮助的板条箱建议。

如果你把 serde(untagged) 放在外部枚举上,而在内部枚举上没有什么特别的,它几乎可以开箱即用:

use serde_derive::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[serde(untagged)]
enum Main {
    A(SubA),
    B(SubB),
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
enum SubA { X1, X2, X3 }

#[derive(Debug, Deserialize, Serialize, PartialEq)]
enum SubB { Y1, Y2, Y3 }

fn main() {
    let x1 = Main::A(SubA::X1);
    let y2 = Main::B(SubB::Y2);

    assert_eq!(serde_json::to_string(&x1).unwrap(), "\"X1\"");
    assert_eq!(serde_json::to_string(&y2).unwrap(), "\"Y2\"");

    assert_eq!(serde_json::de::from_str::<Main>("\"X1\"").unwrap(), x1);
    assert_eq!(serde_json::de::from_str::<Main>("\"Y2\"").unwrap(), y2);
}