Where the struct only has a 'name' field so far.
This commit shows a few new things in rust that we haven't seen
previously:
* The "mod config" to depend on a module contained in config.rs
* The ? operator ("try operator") which unwraps a Result if it is_ok,
and insteadd returns an error if it is not.
* Dependencies on rust packages, (serde_json, and serde with the
"derive" feature") used for the JSON parsing and deserializing.
* The derive attribute (spelled "#[derive(...)]" used to automatically
create implementations of the Debug and Deserialize traits for our
struct. Debug isn't used here, but could be used by passing a
ConfigFile value to println! or format! macros using a "{:?}" format
specifier.
* A closure accepting a single parameter: |e| { ... }
edition = "2024"
[dependencies]
+serde = { version = "1", features = ["derive"]}
+serde_json = "1"
--- /dev/null
+use serde::Deserialize;
+use std::path::Path;
+
+#[derive(Debug, Deserialize)]
+pub struct ConfigFile {
+ pub name: String,
+}
+
+pub fn load_config(path: &Path) -> Result<ConfigFile, Box<dyn std::error::Error>> {
+ let contents = std::fs::read_to_string(path)?;
+ let config: ConfigFile = serde_json::from_str(&contents)?;
+ Ok(config)
+}
+mod config;
+
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
return Err(format!("Usage: {} <race-config.json>", args[0]).into());
}
+ let config_path = std::path::Path::new(&args[1]);
+ let config = config::load_config(config_path).unwrap_or_else(|e| {
+ eprintln!("Error loading config file {}: {}", args[1], e);
+ std::process::exit(1);
+ });
+
+ eprintln!("Race: {}", config.name);
+
Ok(())
}