rust 如何反序列化具有重复键的JSON而不丢失任何值?

rjee0c15  于 2022-12-04  发布在  其他
关注(0)|答案(1)|浏览(120)

我正在尝试对一些具有重复键的JSON进行反序列化,这些键可能是任意数量的。JSON如下所示:

...
"abilities": [
    {
        "ability_id": 5134,
        "ability_level": 3
    }, 
    {
        "ability_id": 5136,
        "ability_level": 3
    }
],
"abilities": [
    {
        "ability_id": 7710,
        "ability_level": 4
    }
]
...

原始json
我的 rust 码是:

#[derive(Deserialize, Debug)]
pub struct Ancient {
    score: usize,
    tower_state: usize,
    barracks_state: usize,
    picks: Option<Vec<HeroId>>,
    bans: Option<Vec<HeroId>>,
    players: Vec<PlayerDetailed>,
    abilities: Option<Vec<Ability>> // has many keys
}

原 rust
结构Ancient是json中另一个结构的一部分。
只有最后一个abilities有很多键,而且也是在变量数字中,我读过this,但无法根据我的喜好更改它(我希望最终用户仍然有一个结构体)。我甚至尝试过#[serde(flatten)],但它只是让所有的东西都变成None。如果可能的话,我也想更改它:

#[derive(Deserialize, Debug)]
pub struct Ancient {
    score: usize,
    tower_state: usize,
    barracks_state: usize,
    picks: Option<Vec<HeroId>>,
    bans: Option<Vec<HeroId>>,
    players: Vec<PlayerDetailed>,
    abilities_list: Option<abilities<Option<Vec<Ability>>>> 
}
ohfgkhjo

ohfgkhjo1#

JSON规范并没有明确禁止重复键,但是大多数实现都会忽略其中的一个键。对于派生的serde::Deserialize实现,如果存在重复键,任何serde反序列化器(包括serde_json)都会出现混乱。
如果你不能改变json格式,你可以为你的一个类型手动实现Deserialize
让我们稍微简化一下结构体和Json。
JSON格式:

{
    "name": "sn99",
    "abilities": [
        {
            "ability_id": 5134,
            "ability_level": 3
        }, 
        {
            "ability_id": 5136,
            "ability_level": 3
        }
    ],
    "abilities": [
        {
            "ability_id": 7710,
            "ability_level": 4
        }
    ]
}

并解析为如下结构:

use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Ability {
    ability_level: u32,
    ability_id: u32,
}

#[derive(Debug)]
struct Abilities(Vec<Ability>);

#[derive(Debug, Deserialize)]
struct Entity {
    name: String,
    #[serde(flatten)]
    abilities: Abilities,
}

请注意,Abilities并不派生Deserialize;我们将手动实现它:
第一次
产生:

Entity {
    name: "sn99",
    abilities: Abilities(
        [
            Ability {
                ability_level: 3,
                ability_id: 5134,
            },
            Ability {
                ability_level: 3,
                ability_id: 5136,
            },
            Ability {
                ability_level: 4,
                ability_id: 7710,
            },
        ],
    ),
}

相关问题