Question

Require a field to be an integer or null, but not missing in JSON

I want to deserialize the following struct using serde_json. The parent_id field should accept an integer or a null, but I want it to return an error if the field is missing.

#[derive(Debug, Serialize, Deserialize)]
pub struct Group {
   pub name: String,
   pub parent_id: Option<i32>,
}

// this is accepted
serde_json::from_value(json!({
   "name": "Group 1",
   "parent_id": null,
});

// this should return an error
serde_json::from_value(json!({
   "name": "Group 1",
});

I tried using the code above, but parent_id would be deserialized into a None even though it doesn't exist.

 5  139  5
1 Jan 1970

Solution

 7

You can deserialize_with with custom function to get the expected behaviour.

use serde::{Deserialize, Deserializer, Serialize};
use serde_json::json;


#[derive(Debug, Serialize, Deserialize)]
pub struct Group {
   pub name: String,
   #[serde(deserialize_with = "Option::deserialize")]
   pub parent_id: Option<i32>,
}

fn main() {
    // thread 'main' panicked at src/main.rs:25:10:
    // called `Result::unwrap()` on an `Err` value: Error("missing field 
    // `parent_id`", line: 0, column: 0)
    let r: Group = serde_json::from_value(json!({
        "name": "Group 1",
     })).unwrap();
    println!("{:?}", r);

}
2024-07-09
user459872