Merge pull request #114 from matthiasbeyer/libimagstore/store-new-behaviour

Store::new(): Create path if nonexistent
This commit is contained in:
Matthias Beyer 2016-01-23 19:57:44 +01:00
commit 24ebe6736e
5 changed files with 100 additions and 16 deletions

57
libimagrt/src/error.rs Normal file
View file

@ -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<Box<Error>>,
}
impl RuntimeError {
pub fn new(kind: RuntimeErrorKind, cause: Option<Box<Error>>) -> 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)
}
}

View file

@ -9,6 +9,7 @@ extern crate libimagstore;
extern crate libimagutil; extern crate libimagutil;
mod configuration; mod configuration;
mod error;
mod logger; mod logger;
pub mod runtime; pub mod runtime;

View file

@ -1,4 +1,5 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::result::Result as RResult;
pub use clap::App; pub use clap::App;
@ -7,6 +8,8 @@ use log;
use log::LogLevelFilter; use log::LogLevelFilter;
use configuration::Configuration; use configuration::Configuration;
use error::RuntimeError;
use error::RuntimeErrorKind;
use logger::ImagLogger; use logger::ImagLogger;
use libimagstore::store::Store; 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. * 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<Runtime<'a>, RuntimeError> {
let matches = cli_spec.get_matches(); let matches = cli_spec.get_matches();
let rtp : PathBuf = matches.value_of("runtimepath").unwrap_or("~/.imag/").into(); let rtp : PathBuf = matches.value_of("runtimepath").unwrap_or("~/.imag/").into();
let storepath = matches.value_of("storepath") let storepath = matches.value_of("storepath")
@ -38,12 +41,17 @@ impl<'a> Runtime<'a> {
spath.push("/store"); spath.push("/store");
spath spath
}); });
Store::new(storepath).map(|store| {
Runtime { Runtime {
cli_matches: matches, cli_matches: matches,
configuration: Configuration::new(&rtp).unwrap_or(Configuration::default()), configuration: Configuration::new(&rtp).unwrap_or(Configuration::default()),
rtp: rtp, rtp: rtp,
store: Store::new(storepath), store: store,
} }
})
.map_err(|e| {
RuntimeError::new(RuntimeErrorKind::Instantiate, Some(Box::new(e)))
})
} }
/** /**

View file

@ -15,6 +15,8 @@ pub enum StoreErrorKind {
OutOfMemory, OutOfMemory,
FileNotFound, FileNotFound,
FileNotCreated, FileNotCreated,
StorePathExists,
StorePathCreate,
// maybe more // maybe more
} }
@ -26,6 +28,8 @@ fn store_error_type_as_str(e: &StoreErrorKind) -> &'static str {
&StoreErrorKind::OutOfMemory => "Out of Memory", &StoreErrorKind::OutOfMemory => "Out of Memory",
&StoreErrorKind::FileNotFound => "File corresponding to ID not found", &StoreErrorKind::FileNotFound => "File corresponding to ID not found",
&StoreErrorKind::FileNotCreated => "File corresponding to ID could not be created", &StoreErrorKind::FileNotCreated => "File corresponding to ID could not be created",
&StoreErrorKind::StorePathExists => "Store path exists",
&StoreErrorKind::StorePathCreate => "Store path create",
} }
} }

View file

@ -54,11 +54,25 @@ pub struct Store {
impl Store { impl Store {
/// Create a new Store object /// Create a new Store object
pub fn new(location: PathBuf) -> Store { pub fn new(location: PathBuf) -> Result<Store> {
Store { 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, location: location,
entries: Arc::new(RwLock::new(HashMap::new())), entries: Arc::new(RwLock::new(HashMap::new())),
} })
} }
/// Creates the Entry at the given location (inside the entry) /// Creates the Entry at the given location (inside the entry)