gpt4 book ai didi

rust - 使用Rust中的Serde从json提升嵌套值可能是可选的

转载 作者:行者123 更新时间:2023-12-03 11:44:16 28 4
gpt4 key购买 nike

我正在使用此解决方案:
Is there a way to omit wrapper/root objects when deserializing objects with Serde?
从嵌套的json结构中提高浮点值:
这是JSON

"activitiesWon": {
"statId": "activitiesWon",
"basic": {
"value": 3.0,
"displayValue": "3"
}
},
这是数据结构和客户反序列化器:
#[derive(Serialize, Deserialize, Debug, Default, Clone, Copy)]
pub struct PvpStatsData {
#[serde(rename = "activitiesWon", deserialize_with="property_to_float")]
pub activities_won:f32,
}

pub fn property_to_float<'de, D>(deserializer: D) -> Result<f32, D::Error>
where D: serde::de::Deserializer<'de>,
{
#[derive(Deserialize)]
struct Outer {
pub basic: Inner,
}

#[derive(Deserialize)]
struct Inner {
pub value: f32,
}

let helper = Outer::deserialize(deserializer)?;
Ok(helper.basic.value)
}
这很好用。但是,某些结构/属性可能不存在,因此它们的字段签名看起来像这样,带有自定义反序列化器,该反序列化器返回Option或None:
#[derive(Serialize, Deserialize, Debug, Default, Clone, Copy)]
pub struct PvpStatsData {
#[serde(rename = "bestSingleGameKills", deserialize_with="property_to_option_float")]
pub best_single_game_kills:Option<f32>,
}

pub fn property_to_option_float<'de, D>(deserializer: D) -> Result<Option<f32>, D::Error>
where D: serde::de::Deserializer<'de>,
{
println!("PARSER");
#[derive(Deserialize, Debug, )]
struct Outer {
pub basic: Inner,
}

#[derive(Deserialize, Debug, )]
struct Inner {
pub value: f32,
}

Option::<Outer>::deserialize(deserializer).map(|o:Option<Outer>| match o {
Some(e) => {
println!("{:?}", e);
Some(e.basic.value)
},
None => None,
})
}
但是,在解析时,如果json中不存在该属性,则会收到解析错误:
serde_json::Error : Error("missing field `bestSingleGameKills`", line: 1, column: 4358)
而且我的自定义反序列化方法从未调用过。
有人知道为什么不调用反序列化方法吗?和/或在属性不存在时如何调用它?我还有其他可以处理Optional结果的反序列化器,但是我怀疑这与嵌套json和option的组合有关。
香港专业教育学院在这里张贴了一个例子的操场:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=022d7ca3513e411644d186518d177645
(只需取消注释第二个json块即可查看问题)

最佳答案

default字段属性应该可以正常工作(我假设您可以,并且在json中不包含best_single_game_kills默认为None的情况)。

#[derive(Deserialize, Debug, Default, Clone, Copy)]
pub struct PvpStatsData {
#[serde(default, rename = "activitiesWon", deserialize_with="property_to_float")]
pub activities_won:f32,

#[serde(default, rename = "bestSingleGameKills", deserialize_with="property_to_option_float")]
pub best_single_game_kills:Option<f32>,
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a50748db2fb585a9430371a6ecd10f82

关于rust - 使用Rust中的Serde从json提升嵌套值可能是可选的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65164276/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com