簡體   English   中英

使用 serde_json 解析時是否可以展平子對象字段?

[英]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. 本身低於頂層

這三種方法都需要不同的方法。 在這個問題中觀察到#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,
}

來自: https : //serde.rs/attr-flatten.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM