home
NOTE: Under Construction - I'm in the middle of upgrading my site and lots of stuff is kinda broken. Please forgive the mess.

Load A Generic JSON Config File In Rust With serde

September 2023

This is how I'm loading config options in from a JSON file in Rust:

Code
```cargo
[dependencies]
serde_json = "1.0"
```

use std::path::PathBuf;
use std::fs;
use serde_json::Value;

fn main() {
  let config_path = PathBuf::from("config-sample.json");
  let config = load_config_file(config_path);
  match config {
    Ok(values) => { dbg!(values); () }
    Err(e) => println!("{}", e)
  }
}

fn load_config_file(path: PathBuf) -> Result<Value, String> {
    match path.try_exists() {
        Ok(exists) => {
            if exists == true {
              let text = fs::read_to_string(&path).unwrap();
              match serde_json::from_str::<Value>(text.as_str()) {
                Ok(data) => { Ok(data) },
                Err(_) => {
                  Err(format!("Could not parse JSON file: {}", &path.display())) 
                }
              }
            } else {
                Err(format!("Could not read JSON file: {}", &path.display())) 
            }
        }
        Err(_) => {
          Err(format!("Could not read JSON file: {}", &path.display())) 
        }
    }
}
Results
[/Users/alan/.cargo/target/55/19854259915251/_active_nvim_run:14:21] values = Object {
    "alfa": String("the quick"),
    "bravo": String("brown fox"),
}
Code
//     if let Some(config) = load_config(PathBuf::from("config.json")) {
  //       dbg!(config);
    // } else {
      //  println!("Could not load config");
   // }
//pub fn load_config(path: PathBuf) -> Option<Config> {
 //    if let Ok(data) = fs::read_to_string(path) {
   //      if let Ok(config) = serde_json::from_str::<Config>(data.as_str()) {
     //       Some(config)
      //  } else {
       //     None
//         }
  //  } else {
   //      None
    // }
// }
  • This requires the crates:

    cargo add serde --features "derive" cargo add serde_json

  • This approach requires defining the strut the JSON gets loaded into in advance. I think there are ways to do it without that. I prefer making the structure explicit.

  • The value that comes back from load_config() is an option. The code in main() checks to see if it loaded and works from there.

═══ § ═══