diff --git a/libimagrt/Cargo.toml b/libimagrt/Cargo.toml index 276295fb..655546b9 100644 --- a/libimagrt/Cargo.toml +++ b/libimagrt/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Matthias Beyer "] [dependencies] clap = "2.1.1" -config = "0.1.3" +toml = "0.1.27" log = "0.3.4" xdg-basedir = "0.2.2" itertools = "0.4.6" diff --git a/libimagrt/src/configuration.rs b/libimagrt/src/configuration.rs index 79ff6ee5..f5f06662 100644 --- a/libimagrt/src/configuration.rs +++ b/libimagrt/src/configuration.rs @@ -1,9 +1,7 @@ -use std::default::Default; use std::path::PathBuf; use std::result::Result as RResult; -pub use config::types::Config; -pub use config::reader::from_file; +use toml::{Parser, Value}; /** * Errors which are related to configuration-file loading @@ -18,7 +16,6 @@ pub mod error { */ #[derive(Clone, Debug, PartialEq)] pub enum ConfigErrorKind { - ConfigNotFound, ConfigParsingFailed, NoConfigFileFound, } @@ -56,7 +53,6 @@ pub mod error { */ pub fn as_str(e: &ConfigError) -> &'static str { match e.kind() { - ConfigErrorKind::ConfigNotFound => "Config not found", ConfigErrorKind::ConfigParsingFailed => "Config parsing failed", ConfigErrorKind::NoConfigFileFound => "No config file found", } @@ -104,6 +100,11 @@ pub type Result = RResult; #[derive(Debug)] pub struct Configuration { + /** + * The plain configuration object for direct access if necessary + */ + config: Value, + /** * The verbosity the program should run with */ @@ -133,9 +134,9 @@ impl Configuration { */ pub fn new(rtp: &PathBuf) -> Result { fetch_config(&rtp).map(|cfg| { - let verbosity = cfg.lookup_boolean("verbosity").unwrap_or(false); - let editor = cfg.lookup_str("editor").map(String::from); - let editor_opts = String::from(cfg.lookup_str("editor-opts").unwrap_or("")); + let verbosity = get_verbosity(&cfg); + let editor = get_editor(&cfg); + let editor_opts = get_editor_opts(&cfg); debug!("Building configuration"); debug!(" - verbosity : {:?}", verbosity); @@ -143,6 +144,7 @@ impl Configuration { debug!(" - editor-opts: {}", editor_opts); Configuration { + config: cfg, verbosity: verbosity, editor: editor, editor_opts: editor_opts, @@ -150,6 +152,36 @@ impl Configuration { }) } + pub fn config(&self) -> &Value { + &self.config + } + +} + +fn get_verbosity(v: &Value) -> bool { + match v { + &Value::Table(ref t) => t.get("verbose") + .map(|v| match v { &Value::Boolean(b) => b, _ => false, }) + .unwrap_or(false), + _ => false, + } +} + +fn get_editor(v: &Value) -> Option { + match v { + &Value::Table(ref t) => t.get("editor") + .and_then(|v| match v { &Value::String(ref s) => Some(s.clone()), _ => None, }), + _ => None, + } +} + +fn get_editor_opts(v: &Value) -> String { + match v { + &Value::Table(ref t) => t.get("editor-opts") + .and_then(|v| match v { &Value::String(ref s) => Some(s.clone()), _ => None, }) + .unwrap_or(String::new()), + _ => String::new(), + } } /** @@ -157,8 +189,10 @@ impl Configuration { * * Tests several variants for the config file path and uses the first one which works. */ -fn fetch_config(rtp: &PathBuf) -> Result { +fn fetch_config(rtp: &PathBuf) -> Result { use std::env; + use std::fs::File; + use std::io::Read; use xdg_basedir; use itertools::Itertools; @@ -184,29 +218,20 @@ fn fetch_config(rtp: &PathBuf) -> Result { .flatten() .filter(|path| path.exists()) .map(|path| { - from_file(&path) - .map_err(|e| { - ConfigError::new(ConfigErrorKind::ConfigParsingFailed, Some(Box::new(e))) - }) + let content = { + let mut s = String::new(); + let mut f = File::open(path); + if f.is_err() { + } + let mut f = f.unwrap(); + f.read_to_string(&mut s); + s + }; + Parser::new(&content[..]).parse() }) - .filter(|loaded| loaded.is_ok()) + .filter(|loaded| loaded.is_some()) .nth(0) - .map(|inner| inner.unwrap()) + .map(|inner| Value::Table(inner.unwrap())) .ok_or(ConfigError::new(ConfigErrorKind::NoConfigFileFound, None)) } -impl Default for Configuration { - - /** - * Get a default configuration object - */ - fn default() -> Configuration { - Configuration { - verbosity: false, - editor: Some(String::from("nano")), - editor_opts: String::from(""), - } - } - -} - diff --git a/libimagrt/src/lib.rs b/libimagrt/src/lib.rs index 9e81f088..4db24dc5 100644 --- a/libimagrt/src/lib.rs +++ b/libimagrt/src/lib.rs @@ -3,7 +3,7 @@ #[cfg(unix)] extern crate xdg_basedir; extern crate clap; -extern crate config; +extern crate toml; extern crate libimagstore; extern crate libimagutil; diff --git a/libimagrt/src/runtime.rs b/libimagrt/src/runtime.rs index 23383b1d..a1cbc63d 100644 --- a/libimagrt/src/runtime.rs +++ b/libimagrt/src/runtime.rs @@ -15,7 +15,7 @@ use libimagstore::store::Store; pub struct Runtime<'a> { rtp: PathBuf, - configuration: Configuration, + configuration: Option, cli_matches: ArgMatches<'a>, store: Store, } @@ -32,6 +32,9 @@ impl<'a> Runtime<'a> { */ pub fn new(cli_spec: App<'a, 'a>) -> Result, RuntimeError> { use std::env; + use std::error::Error; + + use configuration::error::ConfigErrorKind; let matches = cli_spec.get_matches(); let rtp : PathBuf = matches.value_of("runtimepath") @@ -51,10 +54,24 @@ impl<'a> Runtime<'a> { spath.push("store"); spath }); + + let cfg = Configuration::new(&rtp); + let cfg = if cfg.is_err() { + let e = cfg.err().unwrap(); + if e.kind() != ConfigErrorKind::NoConfigFileFound { + let cause : Option> = Some(Box::new(e)); + return Err(RuntimeError::new(RuntimeErrorKind::Instantiate, cause)); + } else { + None + } + } else { + Some(cfg.unwrap()) + }; + Store::new(storepath).map(|store| { Runtime { cli_matches: matches, - configuration: Configuration::new(&rtp).unwrap_or(Configuration::default()), + configuration: cfg, rtp: rtp, store: store, }