Есть ли способ пропустить объекты оболочки / корня при десериализации объектов с помощью Serde? - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть следующий объект:

{
  "data": {
    "id": 1,
    "name": "South America",
    "countries": {
      "data": [
        {
          "id": 122,
          "name": "Brazil",
          "capital": "Brasilia"
        }
      ]
    }
  }
}

Я хотел бы определить две структуры, Continent и Country, исключая обертки data, которые не увеличивают значение.

1 Ответ

0 голосов
/ 12 февраля 2019

Я бы реализовал это, используя структуру-обертку, которую можно использовать непосредственно для сброса верхнего уровня вложенности, а также через атрибут #[serde(with = "...")] для устранения уровней вложенности в десериализованной структуре данных.


use serde::{Deserialize, Deserializer};

#[derive(Deserialize, Debug)]
struct Continent {
    id: u64,
    name: String,
    #[serde(with = "Wrapper")]
    countries: Vec<Country>,
}

#[derive(Deserialize, Debug)]
struct Country {
    id: u64,
    name: String,
    capital: String,
}

#[derive(Deserialize)]
struct Wrapper<T> {
    data: T,
}

impl<T> Wrapper<T> {
    fn deserialize<'de, D>(deserializer: D) -> Result<T, D::Error>
    where
        T: Deserialize<'de>,
        D: Deserializer<'de>,
    {
        let wrapper = <Self as Deserialize>::deserialize(deserializer)?;
        Ok(wrapper.data)
    }
}

fn main() -> serde_json::Result<()> {
    let j = r#"
        {
          "data": {
            "id": 1,
            "name": "South America",
            "countries": {
              "data": [
                {
                  "id": 122,
                  "name": "Brazil",
                  "capital": "Brasilia"
                }
              ]
            }
          }
        }"#;

    let wrapper: Wrapper<Continent> = serde_json::from_str(j)?;
    println!("{:#?}", wrapper.data);

    Ok(())
}

Есть три материально разных места, где возникает незначительное вложение:

  1. рядом с другими полями
  2. само по себе на верхнем уровне
  3. сам по себе ниже верхнего уровня

Все три требуют разных подходов.В этом вопросе рассматриваются # 2 и # 3.

Чтобы решить # 1, см. Можно ли сгладить поля подобъекта при синтаксическом анализе с serde_json?

...