Read JSON with optional fields: Option or default value?
Option
- In this example we expect the JSON to have 3 fields:
name,language, andmarried. nameis required field.languageis optional, if not provided we set a default value.marriedis optional, if not provied we setNone.
The type of the values is not releavant for the example.
use serde::Deserialize;
#[derive(Deserialize, Debug)]
#[allow(dead_code)]
struct Person {
name: String,
#[serde(default = "get_default_language")]
language: String,
married: Option<bool>,
}
fn get_default_language() -> String {
String::from("Rust")
}
fn main() {
let filename = get_filename();
let content = std::fs::read_to_string(filename).unwrap();
let data = serde_json::from_str::<Person>(&content).expect("JSON parsing error");
println!("{:#?}", data);
match data.married {
None => println!("We don't know if {} is married or not", data.name),
Some(val) => println!("Marrige status: {val}"),
}
}
fn get_filename() -> String {
let args: Vec<String> = std::env::args().collect();
if args.len() != 2 {
eprintln!("Usage: {} FILENAME", args[0]);
std::process::exit(1);
}
args[1].to_owned()
}
{
"name": "Foo"
}
$ cargo run -q just_name.json
Person {
name: "Foo",
language: "Rust",
married: None,
}
We don't know if Foo is married or not
{
"married": true,
"language": "Python"
}
$ cargo run -q no_name.json
thread 'main' panicked at src/main.rs:23:57:
JSON parsing error: Error("missing field `name`", line: 4, column: 1)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
{
"name": "Foo",
"married": true
}
$ cargo run -q married_no_language.json
Person {
name: "Foo",
language: "Rust",
married: Some(
true,
),
}
Marrige status: true
{
"name": "Foo",
"married": true,
"language": "Python"
}
$ cargo run -q married_with_python.json
Person {
name: "Foo",
language: "Python",
married: Some(
true,
),
}
Marrige status: true
{
"name": "Foo",
"married": false,
"language": "Python"
}
$ cargo run -q single_with_python.json
Person {
name: "Foo",
language: "Python",
married: Some(
false,
),
}
Marrige status: false