【发布时间】:2022-10-02 08:02:46
【问题描述】:
我正在尝试找到一种反序列化以下 JSON 数据的有效方法:
{
\"filters\": [
{
\"filterType\": \"MIN_FILTER\",
\"min\": 2
},
{
\"filterType\": \"MAX_FILTER\",
\"max\": 10
},
{
\"filterType\": \"PRIORITY_FILTER\",
\"priority\": \"High\"
}
]
}
变成这样:
{
\"filters\": {
\"min\": 2,
\"max:\": 10,
\"priority\": \"High\"
}
}
我刚开始学习 Rust 和 Serde,但到目前为止我能想到的最好的方法是这个自定义的 Deserializer 实现,它首先将每个过滤器反序列化为一个通用的过滤器,其中包含所有可能具有 Option 值的字段:
extern crate serde;
extern crate serde_json;
use serde::{Deserialize, Deserializer};
#[derive(Deserialize, Debug)]
pub struct Object {
filters: Filters,
}
#[derive(Debug)]
pub struct Filters {
min: u32,
max: u32,
priority: String,
}
impl<\'de> Deserialize<\'de> for Filters {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<\'de>,
{
#[derive(Deserialize)]
pub struct GenericFilter {
filterType: String,
priority: Option<String>,
min: Option<u32>,
max: Option<u32>,
}
let filters = Vec::<GenericFilter>::deserialize(deserializer)?;
let mut priority: Option<&String> = None;
let mut min: Option<u32> = None;
let mut max: Option<u32> = None;
for item in filters.iter() {
if item.filterType == \"PRIORITY_FILTER\" {
priority = item.priority.as_ref();
}
if item.filterType == \"MIN_FILTER\" {
min = item.min;
}
if item.filterType == \"MAX_FILTER\" {
max = item.max;
}
}
Ok(Filters {
priority: priority.unwrap().to_owned(),
min: min.unwrap(),
max: max.unwrap(),
})
}
}
fn main() {
let json = r#\"
{
\"filters\": [
{
\"filterType\": \"MIN_FILTER\",
\"min\": 2
},
{
\"filterType\": \"MAX_FILTER\",
\"max\": 10
},
{
\"filterType\": \"PRIORITY_FILTER\",
\"priority\": \"High\"
}
]
}
\"#;
println!(
\"Deserialized = {:#?}\",
serde_json::from_str::<Object>(&json)
);
}
这只是感觉不对,也许有人对此有更好的解决方案? :)
-
一方面,可能想尝试
match而不是 3 个 if 语句。此外,这 3 个 if 语句应该真的是 if-elseif-else :)