diff --git a/Cargo.lock b/Cargo.lock index 5f4ebf3..4c9a42c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,6 +9,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "anyhow" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" + [[package]] name = "async-trait" version = "0.1.42" @@ -1297,6 +1303,7 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" name = "webldappasswd" version = "0.1.0" dependencies = [ + "anyhow", "clap", "handlebars", "ldap3", diff --git a/Cargo.toml b/Cargo.toml index 686e508..d3b2a01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ lto = true codegen-units = 1 [dependencies] +anyhow = "1.0" clap = "2.33" handlebars = "3.5" serde = "1.0" diff --git a/README.md b/README.md index 99e8c80..7d046bf 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ WebLDAPPasswd is published by Philipp Matthias Schäfer WebLDAPPasswd directly depends on the following Rust libraries all published by their copyright holders under the MIT License: +* [*anyhow*](https://github.com/dtolnay/anyhow) * [*clap*](https://clap.rs) * [*serde*](https://serde.rs) * [*serde_derive*](https://serde.rs) diff --git a/src/config.rs b/src/config.rs index 7d99b84..d807676 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,12 +1,11 @@ use std::io::BufReader; use std::fs::File; +use anyhow::{Context, Result}; use handlebars::Handlebars; use serde_derive::Deserialize; use serde_json::json; -use crate::exit::exit_with_error; - fn default_ldap_url() -> String { "ldap://localhost".to_string() } @@ -33,24 +32,17 @@ pub struct Config { pub port: u16, } -pub fn check_config(config: Config) -> Config { - let hb = Handlebars::new(); +pub fn load_config(file_path: &str) -> Result { + let file = File::open(file_path). + with_context(|| format!("Failed to open configuration file '{}'", file_path))?; - if let Some(e) = hb.render_template(&config.dn, &json!({"username" : "foo"})).err() { - exit_with_error(&format!("Failed to parse 'dn' ({}) in configuration file: {}", config.dn, e)) - }; + let config: Config = serde_json::from_reader(BufReader::new(file)) + .with_context(|| format!("Failed to parse configuration file '{}'", file_path))?; - config -} - -pub fn load_config(file_path: &str) -> Config { - let file = match File::open(file_path) { - Ok(file) => file, - Err(_) => exit_with_error(&format!("Failed to open configuration file '{}'", file_path)) - }; - - match serde_json::from_reader(BufReader::new(file)) { - Ok(config) => check_config(config), - Err(_) => exit_with_error(&format!("Failed to parse configuration file '{}'", file_path)) - } + Handlebars::new() + .render_template(&config.dn, &json!({"username" : "foo"})) + .map(|_| ()) + .with_context(|| format!("Failed to parse DN ({}) in configuration file '{}'", config.dn, file_path))?; + + Ok(config) } diff --git a/src/exit.rs b/src/exit.rs deleted file mode 100644 index daed743..0000000 --- a/src/exit.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub fn exit_with_error(message: &str) -> ! { - eprintln!("{}", message); - std::process::exit(-1) -} diff --git a/src/main.rs b/src/main.rs index 651484c..22699f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,19 +2,18 @@ mod api; mod config; -mod exit; mod r#static; +use anyhow::{Context, Result}; use clap::{Arg, App, crate_version}; use rocket::routes; use rocket::config::{Config, Environment}; use crate::config::load_config; -use crate::exit::exit_with_error; const DEFAULT_CONFIG_FILE_PATH: &str = "/etc/webldappasswd/config.json"; -fn main() { +fn main() -> Result<()> { let matches = App::new("WebLDAPPasswd") .version(crate_version!()) .arg(Arg::with_name("config") @@ -29,16 +28,13 @@ fn main() { .value_of("config") .unwrap_or(DEFAULT_CONFIG_FILE_PATH); - let config = load_config(config_file_path); + let config = load_config(config_file_path)?; - let rocket_config_builder = Config::build(Environment::Production) + let rocket_config = Config::build(Environment::Production) .address(&config.host) - .port(config.port); - - let rocket_config = match rocket_config_builder.finalize() { - Ok(config) => config, - Err(e) => exit_with_error(&format!("Bad host address ({}) in configuration file: {}", config.host, e)), - }; + .port(config.port) + .finalize() + .with_context(|| format!("Bad host address ({}) in configuration file '{}'", config.host, config_file_path))?; rocket::custom(rocket_config) .mount("/", routes![r#static::index, @@ -51,4 +47,6 @@ fn main() { api::update]) .manage(config) .launch(); + + Ok(()) }