diff --git a/libimagrt/src/error.rs b/libimagrt/src/error.rs new file mode 100644 index 00000000..6d72cbe0 --- /dev/null +++ b/libimagrt/src/error.rs @@ -0,0 +1,57 @@ +use std::error::Error; +use std::fmt::Display; +use std::fmt::Formatter; +use std::fmt::Error as FmtError; +use std::clone::Clone; + +#[derive(Debug, PartialEq, Clone, Copy)] +pub enum RuntimeErrorKind { + Instantiate, + + // more? +} + +#[derive(Debug)] +pub struct RuntimeError { + kind: RuntimeErrorKind, + cause: Option>, +} + +impl RuntimeError { + + pub fn new(kind: RuntimeErrorKind, cause: Option>) -> RuntimeError { + RuntimeError { + kind: kind, + cause: cause, + } + } + +} + +fn runtime_error_kind_as_str(e: &RuntimeErrorKind) -> &'static str { + match e { + &RuntimeErrorKind::Instantiate => "Could not instantiate", + } +} + +impl Display for RuntimeError { + + fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> { + try!(write!(fmt, "{}", runtime_error_kind_as_str(&self.kind))); + Ok(()) + } + +} + +impl Error for RuntimeError { + + fn description(&self) -> &str { + runtime_error_kind_as_str(&self.kind) + } + + fn cause(&self) -> Option<&Error> { + self.cause.as_ref().map(|e| &**e) + } + +} + diff --git a/libimagrt/src/lib.rs b/libimagrt/src/lib.rs index 58b49dc9..9e81f088 100644 --- a/libimagrt/src/lib.rs +++ b/libimagrt/src/lib.rs @@ -9,6 +9,7 @@ extern crate libimagstore; extern crate libimagutil; mod configuration; +mod error; mod logger; pub mod runtime; diff --git a/libimagrt/src/runtime.rs b/libimagrt/src/runtime.rs index e5a81a57..fe6e87d2 100644 --- a/libimagrt/src/runtime.rs +++ b/libimagrt/src/runtime.rs @@ -1,4 +1,5 @@ use std::path::PathBuf; +use std::result::Result as RResult; pub use clap::App; @@ -7,6 +8,8 @@ use log; use log::LogLevelFilter; use configuration::Configuration; +use error::RuntimeError; +use error::RuntimeErrorKind; use logger::ImagLogger; use libimagstore::store::Store; @@ -28,7 +31,7 @@ impl<'a> Runtime<'a> { * The cli_spec object should be initially build with the ::get_default_cli_builder() function. * */ - pub fn new(cli_spec: App<'a, 'a, 'a, 'a, 'a, 'a>) -> Runtime<'a> { + pub fn new(cli_spec: App<'a, 'a, 'a, 'a, 'a, 'a>) -> Result, RuntimeError> { let matches = cli_spec.get_matches(); let rtp : PathBuf = matches.value_of("runtimepath").unwrap_or("~/.imag/").into(); let storepath = matches.value_of("storepath") @@ -38,12 +41,17 @@ impl<'a> Runtime<'a> { spath.push("/store"); spath }); - Runtime { - cli_matches: matches, - configuration: Configuration::new(&rtp).unwrap_or(Configuration::default()), - rtp: rtp, - store: Store::new(storepath), - } + Store::new(storepath).map(|store| { + Runtime { + cli_matches: matches, + configuration: Configuration::new(&rtp).unwrap_or(Configuration::default()), + rtp: rtp, + store: store, + } + }) + .map_err(|e| { + RuntimeError::new(RuntimeErrorKind::Instantiate, Some(Box::new(e))) + }) } /** diff --git a/libimagstore/src/error.rs b/libimagstore/src/error.rs index e05fcdb6..9dc48bb5 100644 --- a/libimagstore/src/error.rs +++ b/libimagstore/src/error.rs @@ -15,17 +15,21 @@ pub enum StoreErrorKind { OutOfMemory, FileNotFound, FileNotCreated, + StorePathExists, + StorePathCreate, // maybe more } fn store_error_type_as_str(e: &StoreErrorKind) -> &'static str { match e { - &StoreErrorKind::FileError => "File Error", - &StoreErrorKind::IdLocked => "ID locked", - &StoreErrorKind::IdNotFound => "ID not found", - &StoreErrorKind::OutOfMemory => "Out of Memory", - &StoreErrorKind::FileNotFound => "File corresponding to ID not found", - &StoreErrorKind::FileNotCreated => "File corresponding to ID could not be created", + &StoreErrorKind::FileError => "File Error", + &StoreErrorKind::IdLocked => "ID locked", + &StoreErrorKind::IdNotFound => "ID not found", + &StoreErrorKind::OutOfMemory => "Out of Memory", + &StoreErrorKind::FileNotFound => "File corresponding to ID not found", + &StoreErrorKind::FileNotCreated => "File corresponding to ID could not be created", + &StoreErrorKind::StorePathExists => "Store path exists", + &StoreErrorKind::StorePathCreate => "Store path create", } } diff --git a/libimagstore/src/store.rs b/libimagstore/src/store.rs index 89e8ea89..74ffcc58 100644 --- a/libimagstore/src/store.rs +++ b/libimagstore/src/store.rs @@ -54,11 +54,25 @@ pub struct Store { impl Store { /// Create a new Store object - pub fn new(location: PathBuf) -> Store { - Store { + pub fn new(location: PathBuf) -> Result { + use std::fs::create_dir_all; + + if !location.exists() { + let c = create_dir_all(location.clone()); + if c.is_err() { + return Err(StoreError::new(StoreErrorKind::StorePathCreate, + Some(Box::new(c.err().unwrap())))); + } + } else { + if location.is_file() { + return Err(StoreError::new(StoreErrorKind::StorePathExists, None)); + } + } + + Ok(Store { location: location, entries: Arc::new(RwLock::new(HashMap::new())), - } + }) } /// Creates the Entry at the given location (inside the entry)