How do I change Serde's default implementation

2019-08-01 06:39发布

I'm developing an API wrapper and I'm having some troubles with the deserialization of an empty JSON object.

The API returns this JSON object. Mind the empty object at 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
            }
          }
        }
      ]
    }
  ]
}

This is my equivalent struct of the message property (edited):

 #[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's default is to deserialize Options, which are None, with ::serde_json::Value::Null.

1条回答
不美不萌又怎样
2楼-- · 2019-08-01 07:00

I solved this problem differently with no need to change the default implementation. I used serde's field attributes to skip the intent property when the Option is None. Because there is only one property in the struct Intents, this will create an empty object.

#[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,
}
查看更多
登录 后发表回答