编写 TOML 文件以反序列化为结构体中的枚举。

3
如果我有一个带有结构值的枚举,那么正确的TOML格式是什么?
假设我有:
#[derive(Deserialize, Clone)]
pub enum AOrB
{
    A,
    B {
      b1: String,
      b2: String
    },
}

#[derive(Deserialize, Clone)]
pub struct Config
{
    pub z: String,
    pub a_or_b: AOrB
}

我尝试将一个字符串反序列化为Config

fn main()
{
    // What should this be?
    let s = r#"
z = "zzz"

[a_or_b.B]
b1 = "bbb"
b2 = "bbbb"
"#;
    let c: Config = toml::from_str(s).unwrap();
}

我遇到了错误:枚举表必须恰好包含一个表",键:["a_or_b"]。我尝试了一些不同形式的s,但都没有成功。写s的正确方式是什么?

(我需要b1和b2在不同行。)

Playground


更新:看起来如果我将它写成内联样式,就没有问题:

z = "zzz"
a_or_b = { B = { b1 = "bbb", b2 = "bbbb" } }

然而,我确实需要这些字段在不同的行上,因为在我的实际情况中,它们的数量更多且值很长...


1
经过一些初步调查,似乎是“toml”包中的一个错误。让我进一步调查一下。你似乎也不是第一个遇到这个问题的人:https://github.com/toml-rs/toml-rs/issues/390 - Finomnis
看起来已经有一个拉取请求打开了:https://github.com/toml-rs/toml/pull/358 - Finomnis
1个回答

0

这似乎是 toml crate 中的一个 bug。修复方案 已经存在,应该在某个时候合并, 但现在您可能需要直接使用带有修复程序的分支来解决它:

Cargo.toml

[dependencies]
toml = { git = "https://github.com/HarveyHunt/toml", branch = "dotted-table-parsing-toml" }

然后,你的代码就可以正常工作:

use serde::Deserialize;

#[derive(Deserialize, Debug)]
pub enum AOrB {
    A,
    B { b1: String, b2: String },
}

#[derive(Deserialize, Debug)]
pub struct Config {
    pub z: String,
    pub a_or_b: AOrB,
}

fn main() {
    // What should this be?
    let s = r#"
z = "zzz"

[a_or_b.B]
b1 = "bbb"
b2 = "bbbb"
"#;
    let c: Config = toml::from_str(s).unwrap();

    println!("{:#?}", c);
}

Config {
    z: "zzz",
    a_or_b: B {
        b1: "bbb",
        b2: "bbbb",
    },
}

我认为它不支持序列化。但是他们有一个示例文件,展示了反序列化枚举类型,包括数组中带有结构体的枚举类型。https://github.com/toml-rs/toml/blob/main/crates/toml/examples/enum_external.rs。我只是不知道如何为结构体中的枚举类型编写代码... - MetroWind
@MetroWind更新了答案,第一个答案确实没有意义 :) - Finomnis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接