Как мне изменить реализацию Serde по умолчанию, чтобы она возвращала пустой объект вместо null?

Я разрабатываю оболочку API, и у меня возникли проблемы с десериализацией пустого объекта JSON.

API возвращает этот объект JSON. Обратите внимание на пустой объект в entities:

{
  "object": "page",
  "entry": [
    {
      "id": "1158266974317788",
      "messaging": [
        {
          "sender": {
            "id": "some_id"
          },
          "recipient": {
            "id": "some_id"
          },
          "message": {
            "mid": "mid.$cAARHhbMo8SBllWARvlfZBrJc3wnP",
            "seq": 5728,
            "text": "test",
            "nlp": {
              "entities": {} // <-- here
            }
          }
        }
      ]
    }
  ]
}

Это моя эквивалентная структура свойства message (отредактировано):

 #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TextMessage {
    pub mid: String,
    pub seq: u64,
    pub text: String,
    pub nlp: NLP,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NLP {
    pub entities: Intents,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Intents {
    intent: Option<Vec<Intent>>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Intent {
    confidence: f64,
    value: String,
}

По умолчанию Serde десериализует Option, которые равны None, с ::serde_json::Value::Null.


person kper    schedule 28.10.2017    source источник
comment
Почему вы выбрали Vec для представления объекта JSON? Как вы ожидаете передачи этих ценностей? Фактически, если API всегда возвращает объект (или массив, что угодно), почему у вас вообще есть Option в вашей структуре?   -  person Shepmaster    schedule 29.10.2017
comment
Да, вы правы, структура структур была неправильной. Я отредактировал код   -  person kper    schedule 29.10.2017


Ответы (1)


Я решил эту проблему по-другому, без необходимости менять реализацию по умолчанию. Я использовал атрибуты поля serde, чтобы пропустить свойство intent, когда параметр Option равен None. Поскольку в структуре Intents есть только одно свойство, это создаст пустой объект.

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TextMessage {
    pub mid: String,
    pub seq: u64,
    pub text: String,
    pub nlp: NLP,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NLP {
    pub entities: Intents,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Intents {
    #[serde(skip_serializing_if="Option::is_none")]
    intent: Option<Vec<Intent>>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Intent {
    confidence: f64,
    value: String,
}
person kper    schedule 29.10.2017