Read JSON with optional fields: Option or default value?


The type of the values is not releavant for the example.


examples/json/read-with-optional-field/src/main.rs
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()
}

examples/json/read-with-optional-field/just_name.json
{
    "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


examples/json/read-with-optional-field/no_name.json
{
    "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


examples/json/read-with-optional-field/married_no_language.json
{
    "name": "Foo",
    "married": true
}

$ cargo run -q married_no_language.json
Person {
    name: "Foo",
    language: "Rust",
    married: Some(
        true,
    ),
}
Marrige status: true


examples/json/read-with-optional-field/married_with_python.json
{
    "name": "Foo",
    "married": true,
    "language": "Python"
}

$ cargo run -q married_with_python.json
Person {
    name: "Foo",
    language: "Python",
    married: Some(
        true,
    ),
}
Marrige status: true


examples/json/read-with-optional-field/single_with_python.json
{
    "name": "Foo",
    "married": false,
    "language": "Python"
}

$ cargo run -q single_with_python.json
Person {
    name: "Foo",
    language: "Python",
    married: Some(
        false,
    ),
}
Marrige status: false