[英]Is it possible to flatten sub-object fields while parsing with serde_json?
#[serde(rename)]
似乎是正確的選擇,但文檔沒有說明是否可行或如何去做。
這個 JSON 對象:
{
"name" : "myobject"
"info" :
{
"counter" : "3"
"foo" : "bar"
}
}
相應的平面Rust 結構體應該是:
#[derive(Deserialize)]
struct Object {
name: String,
#[serde(rename="info.counter")] // wrong syntax here !!
count: i32,
#[serde(rename="info::foo")] // neither this works
foo: String,
}
沒有使用屬性執行此操作的內置方法,但是您可以為您的Object
類型編寫自己的Deserialize
impl,該實現首先反序列化為一些中間幫助程序表示,然后將數據重新排列為所需的結構。
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use serde::{Deserialize, Deserializer};
#[derive(Debug)]
struct Object {
name: String,
count: i32,
foo: String,
}
impl<'de> Deserialize<'de> for Object {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
#[derive(Deserialize)]
struct Outer {
name: String,
info: Inner,
}
#[derive(Deserialize)]
struct Inner {
count: i32,
foo: String,
}
let helper = Outer::deserialize(deserializer)?;
Ok(Object {
name: helper.name,
count: helper.info.count,
foo: helper.info.foo,
})
}
}
fn main() {
let j = r#"{
"name": "myobject",
"info": {
"count": 3,
"foo": "bar"
}
}"#;
println!("{:#?}", serde_json::from_str::<Object>(j).unwrap());
}
輸出是:
Object {
name: "myobject",
count: 3,
foo: "bar"
}
存在三個本質上不同的地方會出現微不足道的嵌套:
這三種方法都需要不同的方法。 在這個問題中觀察到#1。
要解決 #2 或 #3,請參閱使用 Serde 反序列化對象時是否有辦法省略包裝器/根對象?
現在你可以#[serde(flatten)]
如下:
#[derive(Serialize, Deserialize)]
struct Pagination {
limit: u64,
offset: u64,
total: u64,
}
#[derive(Serialize, Deserialize)]
struct Users {
users: Vec<User>,
#[serde(flatten)]
pagination: Pagination,
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.