commit
2a468be7ab
49 changed files with 405 additions and 484 deletions
|
@ -17,7 +17,7 @@ pub fn create(rt: &Runtime) {
|
|||
.and_then(|i| FromStr::from_str(i).ok())
|
||||
.unwrap_or(0);
|
||||
|
||||
match Counter::new(rt.store(), String::from(name.clone()), init) {
|
||||
match Counter::new(rt.store(), String::from(name), init) {
|
||||
Err(e) => {
|
||||
warn!("Could not create Counter '{}' with initial value '{}'", name, init);
|
||||
trace_error(&e);
|
||||
|
|
|
@ -51,7 +51,7 @@ pub fn interactive(rt: &Runtime) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
let cont = if input.len() > 0 {
|
||||
let cont = if !input.is_empty() {
|
||||
let increment = match input.chars().next() { Some('-') => false, _ => true };
|
||||
input.chars().all(|chr| {
|
||||
match pairs.get_mut(&chr) {
|
||||
|
@ -94,8 +94,8 @@ pub fn interactive(rt: &Runtime) {
|
|||
fn has_quit_binding(pairs: &BTreeMap<char, Binding>) -> bool {
|
||||
pairs.iter()
|
||||
.any(|(_, bind)| {
|
||||
match bind {
|
||||
&Binding::Function(ref name, _) => name == "quit",
|
||||
match *bind {
|
||||
Binding::Function(ref name, _) => name == "quit",
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
|
@ -109,8 +109,8 @@ enum Binding<'a> {
|
|||
impl<'a> Display for Binding<'a> {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> RResult<(), Error> {
|
||||
match self {
|
||||
&Binding::Counter(ref c) => {
|
||||
match *self {
|
||||
Binding::Counter(ref c) => {
|
||||
match c.name() {
|
||||
Ok(name) => {
|
||||
try!(write!(fmt, "{}", name));
|
||||
|
@ -122,7 +122,7 @@ impl<'a> Display for Binding<'a> {
|
|||
},
|
||||
}
|
||||
},
|
||||
&Binding::Function(ref name, _) => write!(fmt, "{}()", name),
|
||||
Binding::Function(ref name, _) => write!(fmt, "{}()", name),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,14 +16,11 @@ pub fn list(rt: &Runtime) {
|
|||
|
||||
if name.is_err() {
|
||||
trace_error(&name.unwrap_err());
|
||||
} else {
|
||||
|
||||
if value.is_err() {
|
||||
} else if value.is_err() {
|
||||
trace_error(&value.unwrap_err());
|
||||
} else {
|
||||
println!("{} - {}", name.unwrap(), value.unwrap());
|
||||
}
|
||||
}
|
||||
})
|
||||
.map_err(|e| trace_error(&e))
|
||||
.ok();
|
||||
|
|
|
@ -81,16 +81,14 @@ fn handle_internal_linking(rt: &Runtime) {
|
|||
|
||||
if cmd.is_present("list") {
|
||||
debug!("List...");
|
||||
for entry in cmd.value_of("list").unwrap().split(",") {
|
||||
for entry in cmd.value_of("list").unwrap().split(',') {
|
||||
debug!("Listing for '{}'", entry);
|
||||
match get_entry_by_name(rt, entry) {
|
||||
Ok(e) => {
|
||||
e.get_internal_links()
|
||||
.map(|links| {
|
||||
let mut i = 0;
|
||||
for link in links.iter().map(|l| l.to_str()).filter_map(|x| x) {
|
||||
for (i, link) in links.iter().map(|l| l.to_str()).filter_map(|x| x).enumerate() {
|
||||
println!("{: <3}: {}", i, link);
|
||||
i += 1;
|
||||
}
|
||||
})
|
||||
.map_err(|e| trace_error(&e))
|
||||
|
@ -275,7 +273,7 @@ fn set_links_for_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLock
|
|||
.value_of("links")
|
||||
.map(String::from)
|
||||
.unwrap()
|
||||
.split(",")
|
||||
.split(',')
|
||||
.map(|uri| {
|
||||
match Url::parse(uri) {
|
||||
Err(e) => {
|
||||
|
@ -299,10 +297,8 @@ fn set_links_for_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLock
|
|||
fn list_links_for_entry(store: &Store, entry: &mut FileLockEntry) {
|
||||
let res = entry.get_external_links(store)
|
||||
.and_then(|links| {
|
||||
let mut i = 0;
|
||||
for link in links {
|
||||
for (i, link) in links.iter().enumerate() {
|
||||
println!("{: <3}: {}", i, link);
|
||||
i += 1;
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
|
|
|
@ -60,11 +60,10 @@ fn create(rt: &Runtime) {
|
|||
.map_err(|e| trace_error(&e))
|
||||
.ok();
|
||||
|
||||
if rt.cli().subcommand_matches("create").unwrap().is_present("edit") {
|
||||
if !edit_entry(rt, name) {
|
||||
if rt.cli().subcommand_matches("create").unwrap().is_present("edit") &&
|
||||
!edit_entry(rt, name) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn delete(rt: &Runtime) {
|
||||
|
|
|
@ -60,30 +60,24 @@ pub fn create(rt: &Runtime) {
|
|||
|
||||
fn create_from_cli_spec(rt: &Runtime, matches: &ArgMatches, path: &PathBuf) -> Result<()> {
|
||||
let content = matches.subcommand_matches("entry")
|
||||
.map(|entry_subcommand| {
|
||||
.map_or_else(|| {
|
||||
debug!("Didn't find entry subcommand, getting raw content");
|
||||
matches.value_of("from-raw")
|
||||
.map_or_else(String::new, string_from_raw_src)
|
||||
}, |entry_subcommand| {
|
||||
debug!("Found entry subcommand, parsing content");
|
||||
entry_subcommand
|
||||
.value_of("content")
|
||||
.map(String::from)
|
||||
.unwrap_or_else(|| {
|
||||
entry_subcommand
|
||||
.value_of("content-from")
|
||||
.map(|src| string_from_raw_src(src))
|
||||
.unwrap_or(String::new())
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
debug!("Didn't find entry subcommand, getting raw content");
|
||||
matches.value_of("from-raw")
|
||||
.map(|raw_src| string_from_raw_src(raw_src))
|
||||
.unwrap_or(String::new())
|
||||
.map_or_else(|| {
|
||||
entry_subcommand.value_of("content-from")
|
||||
.map_or_else(String::new, string_from_raw_src)
|
||||
}, String::from)
|
||||
});
|
||||
|
||||
debug!("Got content with len = {}", content.len());
|
||||
|
||||
let header = matches.subcommand_matches("entry")
|
||||
.map(|entry_matches| build_toml_header(entry_matches, EntryHeader::new()))
|
||||
.unwrap_or(EntryHeader::new());
|
||||
.map_or_else(EntryHeader::new,
|
||||
|entry_matches| build_toml_header(entry_matches, EntryHeader::new()));
|
||||
|
||||
create_with_content_and_header(rt, path, content, header)
|
||||
}
|
||||
|
@ -92,7 +86,7 @@ fn create_from_source(rt: &Runtime, matches: &ArgMatches, path: &PathBuf) -> Res
|
|||
let content = matches
|
||||
.value_of("from-raw")
|
||||
.ok_or(StoreError::new(StoreErrorKind::NoCommandlineCall, None))
|
||||
.map(|raw_src| string_from_raw_src(raw_src));
|
||||
.map(string_from_raw_src);
|
||||
|
||||
if content.is_err() {
|
||||
return content.map(|_| ());
|
||||
|
|
|
@ -3,10 +3,8 @@ use std::fmt::Error as FmtError;
|
|||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/**
|
||||
* Kind of store error
|
||||
*/
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
/// Kind of store error
|
||||
pub enum StoreErrorKind {
|
||||
BackendError,
|
||||
NoCommandlineCall,
|
||||
|
@ -14,9 +12,9 @@ pub enum StoreErrorKind {
|
|||
}
|
||||
|
||||
fn store_error_type_as_str(e: &StoreErrorKind) -> &'static str {
|
||||
match e {
|
||||
&StoreErrorKind::BackendError => "Backend Error",
|
||||
&StoreErrorKind::NoCommandlineCall => "No commandline call",
|
||||
match *e {
|
||||
StoreErrorKind::BackendError => "Backend Error",
|
||||
StoreErrorKind::NoCommandlineCall => "No commandline call",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,9 +35,7 @@ pub struct StoreError {
|
|||
|
||||
impl StoreError {
|
||||
|
||||
/**
|
||||
* Build a new StoreError from an StoreErrorKind, optionally with cause
|
||||
*/
|
||||
///Build a new StoreError from an StoreErrorKind, optionally with cause
|
||||
pub fn new(errtype: StoreErrorKind, cause: Option<Box<Error>>)
|
||||
-> StoreError
|
||||
{
|
||||
|
@ -49,11 +45,9 @@ impl StoreError {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error type of this StoreError
|
||||
*/
|
||||
/// Get the error type of this StoreError
|
||||
pub fn err_type(&self) -> StoreErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -70,7 +64,7 @@ impl Display for StoreError {
|
|||
impl Error for StoreError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
store_error_type_as_str(&self.err_type.clone())
|
||||
store_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::btree_map::{BTreeMap, Entry};
|
||||
use std::str::Split;
|
||||
|
||||
use clap::ArgMatches;
|
||||
|
@ -21,10 +22,10 @@ pub fn build_toml_header(matches: &ArgMatches, header: EntryHeader) -> EntryHead
|
|||
for tpl in kvs {
|
||||
let (key, value) = tpl.into();
|
||||
debug!("Splitting: {:?}", key);
|
||||
let mut split = key.split(".");
|
||||
let mut split = key.split('.');
|
||||
let current = split.next();
|
||||
if current.is_some() {
|
||||
insert_key_into(String::from(current.unwrap()), &mut split, value, &mut main);
|
||||
insert_key_into(String::from(current.unwrap()), &mut split, Cow::Owned(value), &mut main);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,9 +37,9 @@ pub fn build_toml_header(matches: &ArgMatches, header: EntryHeader) -> EntryHead
|
|||
}
|
||||
}
|
||||
|
||||
fn insert_key_into(current: String,
|
||||
rest_path: &mut Split<&str>,
|
||||
value: String,
|
||||
fn insert_key_into<'a>(current: String,
|
||||
rest_path: &mut Split<char>,
|
||||
value: Cow<'a, str>,
|
||||
map: &mut BTreeMap<String, Value>) {
|
||||
let next = rest_path.next();
|
||||
|
||||
|
@ -47,27 +48,30 @@ fn insert_key_into(current: String,
|
|||
map.insert(current, parse_value(value));
|
||||
} else {
|
||||
debug!("Inserting into {:?} ... = {:?}", current, value);
|
||||
if map.contains_key(¤t) {
|
||||
match map.get_mut(¤t).unwrap() {
|
||||
&mut Value::Table(ref mut t) => {
|
||||
match map.entry(current) {
|
||||
Entry::Occupied(ref mut e) => {
|
||||
match *e.get_mut() {
|
||||
Value::Table(ref mut t) => {
|
||||
insert_key_into(String::from(next.unwrap()), rest_path, value, t);
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else {
|
||||
},
|
||||
Entry::Vacant(v) => { v.insert(Value::Table( {
|
||||
let mut submap = BTreeMap::new();
|
||||
insert_key_into(String::from(next.unwrap()), rest_path, value, &mut submap);
|
||||
debug!("Inserting submap = {:?}", submap);
|
||||
map.insert(current, Value::Table(submap));
|
||||
submap }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_value(value: String) -> Value {
|
||||
fn parse_value(value: Cow<str>) -> Value {
|
||||
use std::str::FromStr;
|
||||
|
||||
fn is_ary(v: &String) -> bool {
|
||||
v.chars().next() == Some('[') && v.chars().last() == Some(']') && v.len() >= 3
|
||||
fn is_ary(v: &str) -> bool {
|
||||
v.starts_with('[') && v.ends_with(']') && v.len() >= 3
|
||||
}
|
||||
|
||||
if value == "true" {
|
||||
|
@ -79,7 +83,7 @@ fn parse_value(value: String) -> Value {
|
|||
} else if is_ary(&value) {
|
||||
debug!("Building Array out of: {:?}...", value);
|
||||
let sub = &value[1..(value.len()-1)];
|
||||
Value::Array(sub.split(",").map(|v| parse_value(String::from(v))).collect())
|
||||
Value::Array(sub.split(',').map(|x| parse_value(Cow::from(x))).collect())
|
||||
} else {
|
||||
FromStr::from_str(&value[..])
|
||||
.map(|i: i64| {
|
||||
|
@ -94,7 +98,7 @@ fn parse_value(value: String) -> Value {
|
|||
})
|
||||
.unwrap_or_else(|_| {
|
||||
debug!("Building String out of: {:?}...", value);
|
||||
Value::String(value)
|
||||
Value::String(value.into_owned())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -77,8 +77,7 @@ fn alter(rt: &Runtime, id: &str, add: Option<&str>, rem: Option<&str>, set: Opti
|
|||
.retrieve(path)
|
||||
.map(|mut e| {
|
||||
add.map(|tags| {
|
||||
let tags = tags.split(",");
|
||||
for tag in tags {
|
||||
for tag in tags.split(',') {
|
||||
info!("Adding tag '{}'", tag);
|
||||
if let Err(e) = e.add_tag(String::from(tag)) {
|
||||
trace_error(&e);
|
||||
|
@ -87,8 +86,7 @@ fn alter(rt: &Runtime, id: &str, add: Option<&str>, rem: Option<&str>, set: Opti
|
|||
});
|
||||
|
||||
rem.map(|tags| {
|
||||
let tags = tags.split(",");
|
||||
for tag in tags {
|
||||
for tag in tags.split(',') {
|
||||
info!("Removing tag '{}'", tag);
|
||||
if let Err(e) = e.remove_tag(String::from(tag)) {
|
||||
trace_error(&e);
|
||||
|
@ -98,8 +96,8 @@ fn alter(rt: &Runtime, id: &str, add: Option<&str>, rem: Option<&str>, set: Opti
|
|||
|
||||
set.map(|tags| {
|
||||
info!("Setting tags '{}'", tags);
|
||||
let tags = tags.split(",").map(String::from).collect();
|
||||
if let Err(e) = e.set_tags(tags) {
|
||||
let tags : Vec<_> = tags.split(',').map(String::from).collect();
|
||||
if let Err(e) = e.set_tags(&tags) {
|
||||
trace_error(&e);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/**
|
||||
|
@ -15,11 +14,11 @@ pub enum ViewErrorKind {
|
|||
}
|
||||
|
||||
fn view_error_type_as_str(e: &ViewErrorKind) -> &'static str {
|
||||
match e {
|
||||
&ViewErrorKind::StoreError => "Store error",
|
||||
&ViewErrorKind::NoVersion => "No version specified",
|
||||
&ViewErrorKind::PatternError => "Error in Pattern",
|
||||
&ViewErrorKind::GlobBuildError => "Could not build glob() Argument",
|
||||
match *e {
|
||||
ViewErrorKind::StoreError => "Store error",
|
||||
ViewErrorKind::NoVersion => "No version specified",
|
||||
ViewErrorKind::PatternError => "Error in Pattern",
|
||||
ViewErrorKind::GlobBuildError => "Could not build glob() Argument",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +58,7 @@ impl ViewError {
|
|||
* Get the error type of this ViewError
|
||||
*/
|
||||
pub fn err_type(&self) -> ViewErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,7 +66,7 @@ impl ViewError {
|
|||
impl Display for ViewError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", view_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", view_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,7 @@ impl Display for ViewError {
|
|||
impl Error for ViewError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
view_error_type_as_str(&self.err_type.clone())
|
||||
view_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -129,7 +129,7 @@ fn load_entry<'a>(id: &str,
|
|||
|
||||
let version = {
|
||||
if version.is_none() {
|
||||
let r = id.split("~").last();
|
||||
let r = id.split('~').last();
|
||||
if r.is_none() {
|
||||
warn!("No version");
|
||||
return Err(ViewError::new(ViewErrorKind::NoVersion, None));
|
||||
|
@ -144,7 +144,7 @@ fn load_entry<'a>(id: &str,
|
|||
debug!("Building path from {:?} and {:?}", id, version);
|
||||
let mut path = rt.store().path().clone();
|
||||
|
||||
if id.chars().next() == Some('/') {
|
||||
if id.starts_with('/') {
|
||||
path.push(format!("{}~{}", &id[1..id.len()], version));
|
||||
} else {
|
||||
path.push(format!("{}~{}", id, version));
|
||||
|
@ -161,7 +161,7 @@ fn view_versions_of(id: &str, rt: &Runtime) -> Result<()> {
|
|||
|
||||
let mut path = rt.store().path().clone();
|
||||
|
||||
if id.chars().next() == Some('/') {
|
||||
if id.starts_with('/') {
|
||||
path.push(format!("{}~*", &id[1..id.len()]));
|
||||
} else {
|
||||
path.push(format!("{}~*", id));
|
||||
|
|
|
@ -144,12 +144,12 @@ impl<'a> Counter<'a> {
|
|||
}
|
||||
|
||||
trait FromStoreId {
|
||||
fn from_storeid<'a>(&'a Store, StoreId) -> Result<Counter<'a>>;
|
||||
fn from_storeid(&Store, StoreId) -> Result<Counter>;
|
||||
}
|
||||
|
||||
impl<'a> FromStoreId for Counter<'a> {
|
||||
|
||||
fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Counter<'b>> {
|
||||
fn from_storeid(store: &Store, id: StoreId) -> Result<Counter> {
|
||||
debug!("Loading counter from storeid: '{:?}'", id);
|
||||
match store.retrieve(id) {
|
||||
Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/**
|
||||
|
@ -15,11 +14,11 @@ pub enum CounterErrorKind {
|
|||
}
|
||||
|
||||
fn counter_error_type_as_str(e: &CounterErrorKind) -> &'static str {
|
||||
match e {
|
||||
&CounterErrorKind::StoreReadError => "Store read error",
|
||||
&CounterErrorKind::StoreWriteError => "Store write error",
|
||||
&CounterErrorKind::HeaderTypeError => "Header type error",
|
||||
&CounterErrorKind::HeaderFieldMissingError => "Header field missing error",
|
||||
match *e {
|
||||
CounterErrorKind::StoreReadError => "Store read error",
|
||||
CounterErrorKind::StoreWriteError => "Store write error",
|
||||
CounterErrorKind::HeaderTypeError => "Header type error",
|
||||
CounterErrorKind::HeaderFieldMissingError => "Header field missing error",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +58,7 @@ impl CounterError {
|
|||
* Get the error type of this CounterError
|
||||
*/
|
||||
pub fn err_type(&self) -> CounterErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,7 +66,7 @@ impl CounterError {
|
|||
impl Display for CounterError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", counter_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", counter_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,7 @@ impl Display for CounterError {
|
|||
impl Error for CounterError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
counter_error_type_as_str(&self.err_type.clone())
|
||||
counter_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -14,15 +14,15 @@ struct EqGt {
|
|||
impl Predicate for EqGt {
|
||||
|
||||
fn evaluate(&self, v: Value) -> bool {
|
||||
match &self.comp {
|
||||
&Value::Integer(i) => {
|
||||
match self.comp {
|
||||
Value::Integer(i) => {
|
||||
match v {
|
||||
Value::Integer(j) => i > j,
|
||||
Value::Float(f) => (i as f64) > f,
|
||||
_ => false,
|
||||
}
|
||||
},
|
||||
&Value::Float(f) => {
|
||||
Value::Float(f) => {
|
||||
match v {
|
||||
Value::Integer(i) => f > (i as f64),
|
||||
Value::Float(d) => f > d,
|
||||
|
|
|
@ -27,11 +27,11 @@ impl Filter for FieldIsEmpty {
|
|||
.map(|v| {
|
||||
match v {
|
||||
Some(Value::Array(a)) => a.is_empty(),
|
||||
Some(Value::Boolean(_)) => false,
|
||||
Some(Value::Float(_)) => false,
|
||||
Some(Value::Integer(_)) => false,
|
||||
Some(Value::String(s)) => s.is_empty(),
|
||||
Some(Value::Table(t)) => t.is_empty(),
|
||||
Some(Value::Boolean(_)) |
|
||||
Some(Value::Float(_)) |
|
||||
Some(Value::Integer(_)) => false,
|
||||
_ => true,
|
||||
}
|
||||
})
|
||||
|
|
|
@ -21,11 +21,11 @@ impl Type {
|
|||
|
||||
fn matches(&self, v: &Value) -> bool {
|
||||
match (self, v) {
|
||||
(&Type::String, &Value::String(_)) => true,
|
||||
(&Type::Integer, &Value::Integer(_)) => true,
|
||||
(&Type::Float, &Value::Float(_)) => true,
|
||||
(&Type::Boolean, &Value::Boolean(_)) => true,
|
||||
(&Type::Array, &Value::Array(_)) => true,
|
||||
(&Type::String, &Value::String(_)) |
|
||||
(&Type::Integer, &Value::Integer(_)) |
|
||||
(&Type::Float, &Value::Float(_)) |
|
||||
(&Type::Boolean, &Value::Boolean(_)) |
|
||||
(&Type::Array, &Value::Array(_)) |
|
||||
(&Type::Table, &Value::Table(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -14,15 +14,15 @@ struct EqLt {
|
|||
impl Predicate for EqLt {
|
||||
|
||||
fn evaluate(&self, v: Value) -> bool {
|
||||
match &self.comp {
|
||||
&Value::Integer(i) => {
|
||||
match self.comp {
|
||||
Value::Integer(i) => {
|
||||
match v {
|
||||
Value::Integer(j) => i < j,
|
||||
Value::Float(f) => (i as f64) < f,
|
||||
_ => false,
|
||||
}
|
||||
},
|
||||
&Value::Float(f) => {
|
||||
Value::Float(f) => {
|
||||
match v {
|
||||
Value::Integer(i) => f < (i as f64),
|
||||
Value::Float(d) => f < d,
|
||||
|
|
|
@ -23,7 +23,7 @@ impl Filter for VersionEq {
|
|||
e.get_header()
|
||||
.read("imag.version")
|
||||
.map(|val| {
|
||||
val.map(|v| {
|
||||
val.map_or(false, |v| {
|
||||
match v {
|
||||
Value::String(s) => {
|
||||
match Version::parse(&s[..]) {
|
||||
|
@ -34,7 +34,6 @@ impl Filter for VersionEq {
|
|||
_ => false,
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ impl Filter for VersionGt {
|
|||
e.get_header()
|
||||
.read("imag.version")
|
||||
.map(|val| {
|
||||
val.map(|v| {
|
||||
val.map_or(false, |v| {
|
||||
match v {
|
||||
Value::String(s) => {
|
||||
match Version::parse(&s[..]) {
|
||||
|
@ -34,7 +34,6 @@ impl Filter for VersionGt {
|
|||
_ => false,
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ impl Filter for VersionLt {
|
|||
e.get_header()
|
||||
.read("imag.version")
|
||||
.map(|val| {
|
||||
val.map(|v| {
|
||||
val.map_or(false, |v| {
|
||||
match v {
|
||||
Value::String(s) => {
|
||||
match Version::parse(&s[..]) {
|
||||
|
@ -34,7 +34,6 @@ impl Filter for VersionLt {
|
|||
_ => false,
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
|
|
@ -15,29 +15,29 @@ pub enum LinkErrorKind {
|
|||
}
|
||||
|
||||
fn link_error_type_as_str(e: &LinkErrorKind) -> &'static str {
|
||||
match e {
|
||||
&LinkErrorKind::EntryHeaderReadError
|
||||
match *e {
|
||||
LinkErrorKind::EntryHeaderReadError
|
||||
=> "Error while reading an entry header",
|
||||
|
||||
&LinkErrorKind::EntryHeaderWriteError
|
||||
LinkErrorKind::EntryHeaderWriteError
|
||||
=> "Error while writing an entry header",
|
||||
|
||||
&LinkErrorKind::ExistingLinkTypeWrong
|
||||
LinkErrorKind::ExistingLinkTypeWrong
|
||||
=> "Existing link entry has wrong type",
|
||||
|
||||
&LinkErrorKind::LinkTargetDoesNotExist
|
||||
LinkErrorKind::LinkTargetDoesNotExist
|
||||
=> "Link target does not exist in the store",
|
||||
|
||||
&LinkErrorKind::InternalConversionError
|
||||
LinkErrorKind::InternalConversionError
|
||||
=> "Error while converting values internally",
|
||||
|
||||
&LinkErrorKind::InvalidUri
|
||||
LinkErrorKind::InvalidUri
|
||||
=> "URI is not valid",
|
||||
|
||||
&LinkErrorKind::StoreReadError
|
||||
LinkErrorKind::StoreReadError
|
||||
=> "Store read error",
|
||||
|
||||
&LinkErrorKind::StoreWriteError
|
||||
LinkErrorKind::StoreWriteError
|
||||
=> "Store write error",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ use url::Url;
|
|||
use crypto::sha1::Sha1;
|
||||
use crypto::digest::Digest;
|
||||
|
||||
/// "Link" Type, just an abstraction over FileLockEntry to have some convenience internally.
|
||||
/// "Link" Type, just an abstraction over `FileLockEntry` to have some convenience internally.
|
||||
struct Link<'a> {
|
||||
link: FileLockEntry<'a>
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ impl<'a> Link<'a> {
|
|||
.map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
|
||||
}
|
||||
|
||||
/// Get a link Url object from a FileLockEntry, ignore errors.
|
||||
/// Get a link Url object from a `FileLockEntry`, ignore errors.
|
||||
fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
|
||||
file.get_header()
|
||||
.read("imag.content.uri")
|
||||
|
@ -78,7 +78,7 @@ impl<'a> Link<'a> {
|
|||
match opt {
|
||||
Ok(Some(Value::String(s))) => {
|
||||
Url::parse(&s[..])
|
||||
.map(|s| Some(s))
|
||||
.map(Some)
|
||||
.map_err(|e| LE::new(LEK::EntryHeaderReadError, Some(Box::new(e))))
|
||||
},
|
||||
Ok(None) => Ok(None),
|
||||
|
@ -115,7 +115,7 @@ fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
|
|||
.ok_or(LE::new(LEK::StoreReadError, None))
|
||||
}
|
||||
|
||||
/// Implement ExternalLinker for Entry, hiding the fact that there is no such thing as an external
|
||||
/// Implement `ExternalLinker` for `Entry`, hiding the fact that there is no such thing as an external
|
||||
/// link in an entry, but internal links to other entries which serve as external links, as one
|
||||
/// entry in the store can only have one external link.
|
||||
impl ExternalLinker for Entry {
|
||||
|
|
|
@ -92,9 +92,9 @@ impl InternalLinker for Entry {
|
|||
fn links_into_values(links: Vec<StoreId>) -> Vec<Option<Value>> {
|
||||
links
|
||||
.into_iter()
|
||||
.map(|s| s.to_str().map(|s| String::from(s)))
|
||||
.map(|s| s.to_str().map(String::from))
|
||||
.unique()
|
||||
.map(|elem| elem.map(|s| Value::String(s)))
|
||||
.map(|elem| elem.map(Value::String))
|
||||
.sorted_by(|a, b| {
|
||||
match (a, b) {
|
||||
(&Some(Value::String(ref a)), &Some(Value::String(ref b))) => Ord::cmp(a, b),
|
||||
|
@ -160,7 +160,7 @@ fn process_rw_result(links: StoreResult<Option<Value>>) -> Result<Vec<Link>> {
|
|||
}
|
||||
};
|
||||
|
||||
if !links.iter().all(|l| match l { &Value::String(_) => true, _ => false }) {
|
||||
if !links.iter().all(|l| match *l { Value::String(_) => true, _ => false }) {
|
||||
debug!("At least one of the Values which were expected in the Array of links is a non-String!");
|
||||
debug!("Generating LinkError");
|
||||
return Err(LinkError::new(LinkErrorKind::ExistingLinkTypeWrong, None));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/**
|
||||
|
@ -15,11 +14,11 @@ pub enum ListErrorKind {
|
|||
}
|
||||
|
||||
fn counter_error_type_as_str(err: &ListErrorKind) -> &'static str{
|
||||
match err {
|
||||
&ListErrorKind::FormatError => "FormatError",
|
||||
&ListErrorKind::EntryError => "EntryError",
|
||||
&ListErrorKind::IterationError => "IterationError",
|
||||
&ListErrorKind::CLIError => "No CLI subcommand for listing entries",
|
||||
match *err {
|
||||
ListErrorKind::FormatError => "FormatError",
|
||||
ListErrorKind::EntryError => "EntryError",
|
||||
ListErrorKind::IterationError => "IterationError",
|
||||
ListErrorKind::CLIError => "No CLI subcommand for listing entries",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +56,7 @@ impl ListError {
|
|||
* Get the error type of this ListError
|
||||
*/
|
||||
pub fn err_type(&self) -> ListErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,7 +64,7 @@ impl ListError {
|
|||
impl Display for ListError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", counter_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", counter_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -74,7 +73,7 @@ impl Display for ListError {
|
|||
impl Error for ListError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
counter_error_type_as_str(&self.err_type.clone())
|
||||
counter_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
@ -12,11 +11,11 @@ pub enum TagErrorKind {
|
|||
}
|
||||
|
||||
fn tag_error_type_as_str(e: &TagErrorKind) -> &'static str {
|
||||
match e {
|
||||
&TagErrorKind::TagTypeError => "Entry Header Tag Type wrong",
|
||||
&TagErrorKind::HeaderReadError => "Error while reading entry header",
|
||||
&TagErrorKind::HeaderWriteError => "Error while writing entry header",
|
||||
&TagErrorKind::NotATag => "String is not a tag",
|
||||
match *e {
|
||||
TagErrorKind::TagTypeError => "Entry Header Tag Type wrong",
|
||||
TagErrorKind::HeaderReadError => "Error while reading entry header",
|
||||
TagErrorKind::HeaderWriteError => "Error while writing entry header",
|
||||
TagErrorKind::NotATag => "String is not a tag",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +48,7 @@ impl TagError {
|
|||
impl Display for TagError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", tag_error_type_as_str(&self.kind.clone())));
|
||||
try!(write!(fmt, "[{}]", tag_error_type_as_str(&self.kind)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ impl Display for TagError {
|
|||
impl Error for TagError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
tag_error_type_as_str(&self.kind.clone())
|
||||
tag_error_type_as_str(&self.kind)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -7,22 +7,20 @@ use tagable::*;
|
|||
use ui::{get_add_tags, get_remove_tags};
|
||||
|
||||
pub fn exec_cli_for_entry(matches: &ArgMatches, entry: &mut FileLockEntry) -> Result<()> {
|
||||
match get_add_tags(matches) {
|
||||
Some(ts) => for t in ts {
|
||||
if let Some(ts) = get_add_tags(matches) {
|
||||
for t in ts {
|
||||
if let Err(e) = entry.add_tag(t) {
|
||||
return Err(e);
|
||||
}
|
||||
},
|
||||
None => { },
|
||||
}
|
||||
}
|
||||
|
||||
match get_remove_tags(matches) {
|
||||
Some(ts) => for t in ts {
|
||||
if let Some(ts) = get_remove_tags(matches) {
|
||||
for t in ts {
|
||||
if let Err(e) = entry.remove_tag(t) {
|
||||
return Err(e);
|
||||
}
|
||||
},
|
||||
None => { },
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
pub type Tag = String;
|
||||
pub type TagSlice<'a> = &'a str;
|
||||
|
|
|
@ -7,7 +7,7 @@ use libimagstore::store::{Entry, EntryHeader, FileLockEntry};
|
|||
|
||||
use error::{TagError, TagErrorKind};
|
||||
use result::Result;
|
||||
use tag::Tag;
|
||||
use tag::{Tag, TagSlice};
|
||||
use util::is_tag;
|
||||
|
||||
use toml::Value;
|
||||
|
@ -15,13 +15,13 @@ use toml::Value;
|
|||
pub trait Tagable {
|
||||
|
||||
fn get_tags(&self) -> Result<Vec<Tag>>;
|
||||
fn set_tags(&mut self, ts: Vec<Tag>) -> Result<()>;
|
||||
fn set_tags(&mut self, ts: &[Tag]) -> Result<()>;
|
||||
|
||||
fn add_tag(&mut self, t: Tag) -> Result<()>;
|
||||
fn remove_tag(&mut self, t: Tag) -> Result<()>;
|
||||
|
||||
fn has_tag(&self, t: &Tag) -> Result<bool>;
|
||||
fn has_tags(&self, ts: &Vec<Tag>) -> Result<bool>;
|
||||
fn has_tag(&self, t: TagSlice) -> Result<bool>;
|
||||
fn has_tags(&self, ts: &[Tag]) -> Result<bool>;
|
||||
|
||||
}
|
||||
|
||||
|
@ -37,11 +37,11 @@ impl Tagable for EntryHeader {
|
|||
|
||||
match tags {
|
||||
Some(Value::Array(tags)) => {
|
||||
if !tags.iter().all(|t| match t { &Value::String(_) => true, _ => false }) {
|
||||
if !tags.iter().all(|t| match *t { Value::String(_) => true, _ => false }) {
|
||||
return Err(TagError::new(TagErrorKind::TagTypeError, None));
|
||||
}
|
||||
if tags.iter().any(|t| match t {
|
||||
&Value::String(ref s) => !is_tag(&s),
|
||||
if tags.iter().any(|t| match *t {
|
||||
Value::String(ref s) => !is_tag(s),
|
||||
_ => unreachable!()})
|
||||
{
|
||||
return Err(TagError::new(TagErrorKind::NotATag, None));
|
||||
|
@ -62,7 +62,7 @@ impl Tagable for EntryHeader {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_tags(&mut self, ts: Vec<Tag>) -> Result<()> {
|
||||
fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
|
||||
if ts.iter().any(|tag| !is_tag(tag)) {
|
||||
debug!("Not a tag: '{}'", ts.iter().filter(|t| !is_tag(t)).next().unwrap());
|
||||
return Err(TagError::new(TagErrorKind::NotATag, None));
|
||||
|
@ -83,7 +83,7 @@ impl Tagable for EntryHeader {
|
|||
self.get_tags()
|
||||
.map(|mut tags| {
|
||||
tags.push(t);
|
||||
self.set_tags(tags.into_iter().unique().collect())
|
||||
self.set_tags(&tags.into_iter().unique().collect::<Vec<_>>()[..])
|
||||
})
|
||||
.map(|_| ())
|
||||
}
|
||||
|
@ -97,12 +97,12 @@ impl Tagable for EntryHeader {
|
|||
self.get_tags()
|
||||
.map(|mut tags| {
|
||||
tags.retain(|tag| tag.clone() != t);
|
||||
self.set_tags(tags)
|
||||
self.set_tags(&tags[..])
|
||||
})
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
fn has_tag(&self, t: &Tag) -> Result<bool> {
|
||||
fn has_tag(&self, t: TagSlice) -> Result<bool> {
|
||||
let tags = self.read("imag.tags");
|
||||
if tags.is_err() {
|
||||
let kind = TagErrorKind::HeaderReadError;
|
||||
|
@ -110,21 +110,21 @@ impl Tagable for EntryHeader {
|
|||
}
|
||||
let tags = tags.unwrap();
|
||||
|
||||
if !tags.iter().all(|t| match t { &Value::String(_) => true, _ => false }) {
|
||||
if !tags.iter().all(|t| match *t { Value::String(_) => true, _ => false }) {
|
||||
return Err(TagError::new(TagErrorKind::TagTypeError, None));
|
||||
}
|
||||
|
||||
Ok(tags
|
||||
.iter()
|
||||
.any(|tag| {
|
||||
match tag {
|
||||
&Value::String(ref s) => { s == t },
|
||||
match *tag {
|
||||
Value::String(ref s) => { s == t },
|
||||
_ => unreachable!()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn has_tags(&self, tags: &Vec<Tag>) -> Result<bool> {
|
||||
fn has_tags(&self, tags: &[Tag]) -> Result<bool> {
|
||||
let mut result = true;
|
||||
for tag in tags {
|
||||
let check = self.has_tag(tag);
|
||||
|
@ -147,7 +147,7 @@ impl Tagable for Entry {
|
|||
self.get_header().get_tags()
|
||||
}
|
||||
|
||||
fn set_tags(&mut self, ts: Vec<Tag>) -> Result<()> {
|
||||
fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
|
||||
self.get_header_mut().set_tags(ts)
|
||||
}
|
||||
|
||||
|
@ -159,11 +159,11 @@ impl Tagable for Entry {
|
|||
self.get_header_mut().remove_tag(t)
|
||||
}
|
||||
|
||||
fn has_tag(&self, t: &Tag) -> Result<bool> {
|
||||
fn has_tag(&self, t: TagSlice) -> Result<bool> {
|
||||
self.get_header().has_tag(t)
|
||||
}
|
||||
|
||||
fn has_tags(&self, ts: &Vec<Tag>) -> Result<bool> {
|
||||
fn has_tags(&self, ts: &[Tag]) -> Result<bool> {
|
||||
self.get_header().has_tags(ts)
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ impl<'a> Tagable for FileLockEntry<'a> {
|
|||
self.deref().get_tags()
|
||||
}
|
||||
|
||||
fn set_tags(&mut self, ts: Vec<Tag>) -> Result<()> {
|
||||
fn set_tags(&mut self, ts: &[Tag]) -> Result<()> {
|
||||
self.deref_mut().set_tags(ts)
|
||||
}
|
||||
|
||||
|
@ -187,11 +187,11 @@ impl<'a> Tagable for FileLockEntry<'a> {
|
|||
self.deref_mut().remove_tag(t)
|
||||
}
|
||||
|
||||
fn has_tag(&self, t: &Tag) -> Result<bool> {
|
||||
fn has_tag(&self, t: TagSlice) -> Result<bool> {
|
||||
self.deref().has_tag(t)
|
||||
}
|
||||
|
||||
fn has_tags(&self, ts: &Vec<Tag>) -> Result<bool> {
|
||||
fn has_tags(&self, ts: &[Tag]) -> Result<bool> {
|
||||
self.deref().has_tags(ts)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use clap::{Arg, ArgMatches, App, SubCommand};
|
|||
|
||||
use tag::Tag;
|
||||
|
||||
/// Generates a clap::SubCommand to be integrated in the commandline-ui builder for building a
|
||||
/// Generates a `clap::SubCommand` to be integrated in the commandline-ui builder for building a
|
||||
/// "tags --add foo --remove bar" subcommand to do tagging action.
|
||||
pub fn tag_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||
SubCommand::with_name(tag_subcommand_name())
|
||||
|
@ -41,7 +41,7 @@ pub fn tag_subcommand_names() -> Vec<&'static str> {
|
|||
vec![tag_subcommand_add_arg_name(), tag_subcommand_remove_arg_name()]
|
||||
}
|
||||
|
||||
/// Generates a clap::Arg which can be integrated into the commandline-ui builder for building a
|
||||
/// Generates a `clap::Arg` which can be integrated into the commandline-ui builder for building a
|
||||
/// "-t" or "--tags" argument which takes values for tagging actions (add, remove)
|
||||
pub fn tag_argument<'a, 'b>() -> Arg<'a, 'b> {
|
||||
Arg::with_name(tag_argument_name())
|
||||
|
@ -79,7 +79,7 @@ fn extract_tags(matches: &ArgMatches, specifier: &str, specchar: char) -> Option
|
|||
.map(|argmatches| {
|
||||
argmatches
|
||||
.map(String::from)
|
||||
.filter(|s| s.chars().next() == Some(specchar))
|
||||
.filter(|s| s.starts_with(specchar))
|
||||
.map(|s| {
|
||||
String::from(s.split_at(1).1)
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use regex::Regex;
|
||||
|
||||
pub fn is_tag(s: &String) -> bool {
|
||||
Regex::new("^[a-zA-Z]([a-zA-Z0-9_-]*)$").unwrap().captures(&s[..]).is_some()
|
||||
pub fn is_tag(s: &str) -> bool {
|
||||
Regex::new("^[a-zA-Z]([a-zA-Z0-9_-]*)$").unwrap().captures(s).is_some()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/**
|
||||
|
@ -52,7 +51,7 @@ impl ViewError {
|
|||
* Get the error type of this ViewError
|
||||
*/
|
||||
pub fn err_type(&self) -> ViewErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -60,7 +59,7 @@ impl ViewError {
|
|||
impl Display for ViewError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", counter_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", counter_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -69,7 +68,7 @@ impl Display for ViewError {
|
|||
impl Error for ViewError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
counter_error_type_as_str(&self.err_type.clone())
|
||||
counter_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -40,14 +40,11 @@ fn ask_bool_<R: BufRead>(s: &str, default: Option<bool>, input: &mut R) -> bool
|
|||
return true
|
||||
} else if R_NO.is_match(&s[..]) {
|
||||
return false
|
||||
} else {
|
||||
if default.is_some() {
|
||||
} else if default.is_some() {
|
||||
return default.unwrap();
|
||||
}
|
||||
|
||||
// else again...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Ask the user for an unsigned number. Optionally provide a default value. If none is provided,
|
||||
|
@ -123,18 +120,17 @@ pub fn ask_string_<R: BufRead>(s: &str,
|
|||
let _ = input.read_line(&mut s);
|
||||
|
||||
if permit_multiline {
|
||||
if permit_multiline && eof.map(|e| e == s).unwrap_or(false) {
|
||||
if permit_multiline && eof.map_or(false, |e| e == s) {
|
||||
return v.join("\n");
|
||||
}
|
||||
|
||||
if permit_empty || v.len() != 0 {
|
||||
if permit_empty || !v.is_empty() {
|
||||
v.push(s);
|
||||
}
|
||||
print!("{}", prompt);
|
||||
} else {
|
||||
if s.len() == 0 && permit_empty {
|
||||
} else if s.is_empty() && permit_empty {
|
||||
return s;
|
||||
} else if s.len() == 0 && !permit_empty {
|
||||
} else if s.is_empty() && !permit_empty {
|
||||
if default.is_some() {
|
||||
return default.unwrap();
|
||||
} else {
|
||||
|
@ -144,7 +140,6 @@ pub fn ask_string_<R: BufRead>(s: &str,
|
|||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ask_select_from_list(list: &[&str]) -> Result<String> {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/**
|
||||
|
@ -12,8 +11,8 @@ pub enum InteractionErrorKind {
|
|||
}
|
||||
|
||||
fn interaction_error_type_as_str(e: &InteractionErrorKind) -> &'static str {
|
||||
match e {
|
||||
&InteractionErrorKind::Unknown => "Unknown Error",
|
||||
match *e {
|
||||
InteractionErrorKind::Unknown => "Unknown Error",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +49,7 @@ impl InteractionError {
|
|||
* Get the error type of this InteractionError
|
||||
*/
|
||||
pub fn err_type(&self) -> InteractionErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,7 +57,7 @@ impl InteractionError {
|
|||
impl Display for InteractionError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", interaction_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", interaction_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -67,7 +66,7 @@ impl Display for InteractionError {
|
|||
impl Error for InteractionError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
interaction_error_type_as_str(&self.err_type.clone())
|
||||
interaction_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/**
|
||||
|
@ -16,11 +15,11 @@ pub enum NoteErrorKind {
|
|||
}
|
||||
|
||||
fn note_error_type_as_str(e: &NoteErrorKind) -> &'static str {
|
||||
match e {
|
||||
&NoteErrorKind::StoreWriteError => "Error writing store",
|
||||
&NoteErrorKind::StoreReadError => "Error reading store",
|
||||
&NoteErrorKind::HeaderTypeError => "Header type error",
|
||||
&NoteErrorKind::NoteToEntryConversion => "Error converting Note instance to Entry instance",
|
||||
match *e {
|
||||
NoteErrorKind::StoreWriteError => "Error writing store",
|
||||
NoteErrorKind::StoreReadError => "Error reading store",
|
||||
NoteErrorKind::HeaderTypeError => "Header type error",
|
||||
NoteErrorKind::NoteToEntryConversion => "Error converting Note instance to Entry instance",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ impl NoteError {
|
|||
* Get the error type of this NoteError
|
||||
*/
|
||||
pub fn err_type(&self) -> NoteErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,7 +65,7 @@ impl NoteError {
|
|||
impl Display for NoteError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", note_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", note_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -75,7 +74,7 @@ impl Display for NoteError {
|
|||
impl Error for NoteError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
note_error_type_as_str(&self.err_type.clone())
|
||||
note_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -10,7 +10,7 @@ use libimagstore::storeid::StoreId;
|
|||
use libimagstore::storeid::StoreIdIterator;
|
||||
use libimagstore::store::FileLockEntry;
|
||||
use libimagstore::store::Store;
|
||||
use libimagentrytag::tag::Tag;
|
||||
use libimagentrytag::tag::{Tag, TagSlice};
|
||||
use libimagentrytag::tagable::Tagable;
|
||||
use libimagentrytag::result::Result as TagResult;
|
||||
|
||||
|
@ -124,7 +124,7 @@ impl<'a> Tagable for Note<'a> {
|
|||
self.entry.get_tags()
|
||||
}
|
||||
|
||||
fn set_tags(&mut self, ts: Vec<Tag>) -> TagResult<()> {
|
||||
fn set_tags(&mut self, ts: &[Tag]) -> TagResult<()> {
|
||||
self.entry.set_tags(ts)
|
||||
}
|
||||
|
||||
|
@ -136,23 +136,23 @@ impl<'a> Tagable for Note<'a> {
|
|||
self.entry.remove_tag(t)
|
||||
}
|
||||
|
||||
fn has_tag(&self, t: &Tag) -> TagResult<bool> {
|
||||
fn has_tag(&self, t: TagSlice) -> TagResult<bool> {
|
||||
self.entry.has_tag(t)
|
||||
}
|
||||
|
||||
fn has_tags(&self, ts: &Vec<Tag>) -> TagResult<bool> {
|
||||
fn has_tags(&self, ts: &[Tag]) -> TagResult<bool> {
|
||||
self.entry.has_tags(ts)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
trait FromStoreId {
|
||||
fn from_storeid<'a>(&'a Store, StoreId) -> Result<Note<'a>>;
|
||||
fn from_storeid(&Store, StoreId) -> Result<Note>;
|
||||
}
|
||||
|
||||
impl<'a> FromStoreId for Note<'a> {
|
||||
|
||||
fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Note<'b>> {
|
||||
fn from_storeid(store: &Store, id: StoreId) -> Result<Note> {
|
||||
debug!("Loading note from storeid: '{:?}'", id);
|
||||
match store.retrieve(id) {
|
||||
Err(e) => Err(NE::new(NEK::StoreReadError, Some(Box::new(e)))),
|
||||
|
|
|
@ -12,17 +12,13 @@ pub mod error {
|
|||
use std::fmt::{Display, Formatter};
|
||||
use std::fmt::Error as FmtError;
|
||||
|
||||
/**
|
||||
* The kind of an error
|
||||
*/
|
||||
/// The kind of an error
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ConfigErrorKind {
|
||||
NoConfigFileFound,
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration error type
|
||||
*/
|
||||
/// Configuration error type
|
||||
#[derive(Debug)]
|
||||
pub struct ConfigError {
|
||||
kind: ConfigErrorKind,
|
||||
|
@ -31,9 +27,7 @@ pub mod error {
|
|||
|
||||
impl ConfigError {
|
||||
|
||||
/**
|
||||
* Instantiate a new ConfigError, optionally with cause
|
||||
*/
|
||||
/// Instantiate a new `ConfigError`, optionally with cause
|
||||
pub fn new(kind: ConfigErrorKind, cause: Option<Box<Error>>) -> ConfigError {
|
||||
ConfigError {
|
||||
kind: kind,
|
||||
|
@ -41,16 +35,12 @@ pub mod error {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the Kind of the Error
|
||||
*/
|
||||
///get the Kind of the Error
|
||||
pub fn err_type(&self) -> ConfigErrorKind {
|
||||
self.kind.clone()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string, the ConfigError can be described with
|
||||
*/
|
||||
/// Get the string, the `ConfigError` can be described with
|
||||
pub fn as_str(e: &ConfigError) -> &'static str {
|
||||
match e.err_type() {
|
||||
ConfigErrorKind::NoConfigFileFound => "No config file found",
|
||||
|
@ -86,51 +76,39 @@ use self::error::{ConfigError, ConfigErrorKind};
|
|||
|
||||
|
||||
/**
|
||||
* Result type of this module. Either T or ConfigError
|
||||
* Result type of this module. Either `T` or `ConfigError`
|
||||
*/
|
||||
pub type Result<T> = RResult<T, ConfigError>;
|
||||
|
||||
/**
|
||||
* Configuration object
|
||||
*
|
||||
* Holds all config variables which are globally available plus the configuration object from the
|
||||
* config parser, which can be accessed.
|
||||
*/
|
||||
/// `Configuration` object
|
||||
///
|
||||
/// Holds all config variables which are globally available plus the configuration object from the
|
||||
/// config parser, which can be accessed.
|
||||
#[derive(Debug)]
|
||||
pub struct Configuration {
|
||||
|
||||
/**
|
||||
* The plain configuration object for direct access if necessary
|
||||
*/
|
||||
/// The plain configuration object for direct access if necessary
|
||||
config: Value,
|
||||
|
||||
/**
|
||||
* The verbosity the program should run with
|
||||
*/
|
||||
/// The verbosity the program should run with
|
||||
verbosity: bool,
|
||||
|
||||
/**
|
||||
* The editor which should be used
|
||||
*/
|
||||
/// The editor which should be used
|
||||
editor: Option<String>,
|
||||
|
||||
/**
|
||||
* The options the editor should get when opening some file
|
||||
*/
|
||||
///The options the editor should get when opening some file
|
||||
editor_opts: String,
|
||||
}
|
||||
|
||||
impl Configuration {
|
||||
|
||||
/**
|
||||
* Get a new configuration object.
|
||||
*
|
||||
* The passed runtimepath is used for searching the configuration file, whereas several file
|
||||
* names are tested. If that does not work, the home directory and the XDG basedir are tested
|
||||
* with all variants.
|
||||
*
|
||||
* If that doesn't work either, an error is returned.
|
||||
*/
|
||||
/// Get a new configuration object.
|
||||
///
|
||||
/// The passed runtimepath is used for searching the configuration file, whereas several file
|
||||
/// names are tested. If that does not work, the home directory and the XDG basedir are tested
|
||||
/// with all variants.
|
||||
///
|
||||
/// If that doesn't work either, an error is returned.
|
||||
pub fn new(rtp: &PathBuf) -> Result<Configuration> {
|
||||
fetch_config(&rtp).map(|cfg| {
|
||||
let verbosity = get_verbosity(&cfg);
|
||||
|
@ -161,8 +139,8 @@ impl Configuration {
|
|||
}
|
||||
|
||||
pub fn store_config(&self) -> Option<&Value> {
|
||||
match &self.config {
|
||||
&Value::Table(ref tabl) => tabl.get("store"),
|
||||
match self.config {
|
||||
Value::Table(ref tabl) => tabl.get("store"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -179,27 +157,26 @@ impl Deref for Configuration {
|
|||
}
|
||||
|
||||
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),
|
||||
match *v {
|
||||
Value::Table(ref t) => t.get("verbose")
|
||||
.map_or(false, |v| match *v { Value::Boolean(b) => b, _ => false, }),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_editor(v: &Value) -> Option<String> {
|
||||
match v {
|
||||
&Value::Table(ref t) => t.get("editor")
|
||||
.and_then(|v| match v { &Value::String(ref s) => Some(s.clone()), _ => None, }),
|
||||
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()),
|
||||
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_default(),
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +201,7 @@ fn fetch_config(rtp: &PathBuf) -> Result<Value> {
|
|||
let variants = vec!["config", "config.toml", "imagrc", "imagrc.toml"];
|
||||
let modifier = |base: &PathBuf, v: &'static str| {
|
||||
let mut base = base.clone();
|
||||
base.push(format!("{}", v));
|
||||
base.push(String::from(v));
|
||||
base
|
||||
};
|
||||
|
||||
|
@ -268,6 +245,6 @@ fn fetch_config(rtp: &PathBuf) -> Result<Value> {
|
|||
.filter(|loaded| loaded.is_some())
|
||||
.nth(0)
|
||||
.map(|inner| Value::Table(inner.unwrap()))
|
||||
.ok_or(ConfigError::new(ConfigErrorKind::NoConfigFileFound, None))
|
||||
.ok_or_else(|| ConfigError::new(ConfigErrorKind::NoConfigFileFound, None))
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,10 @@ impl RuntimeError {
|
|||
}
|
||||
|
||||
fn runtime_error_kind_as_str(e: &RuntimeErrorKind) -> &'static str {
|
||||
match e {
|
||||
&RuntimeErrorKind::Instantiate => "Could not instantiate",
|
||||
&RuntimeErrorKind::IOError => "IO Error",
|
||||
&RuntimeErrorKind::ProcessExitFailure => "Process exited with failure",
|
||||
match *e {
|
||||
RuntimeErrorKind::Instantiate => "Could not instantiate",
|
||||
RuntimeErrorKind::IOError => "IO Error",
|
||||
RuntimeErrorKind::ProcessExitFailure => "Process exited with failure",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,22 +55,20 @@ impl<'a> Runtime<'a> {
|
|||
Runtime::init_logger(is_debugging, is_verbose);
|
||||
|
||||
let rtp : PathBuf = matches.value_of("runtimepath")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
.map_or_else(|| {
|
||||
env::var("HOME")
|
||||
.map(PathBuf::from)
|
||||
.map(|mut p| { p.push(".imag"); p})
|
||||
.unwrap_or_else(|_| {
|
||||
panic!("You seem to be $HOME-less. Please get a $HOME before using this software. We are sorry for you and hope you have some accommodation anyways.");
|
||||
})
|
||||
});
|
||||
}, PathBuf::from);
|
||||
let storepath = matches.value_of("storepath")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or({
|
||||
.map_or_else(|| {
|
||||
let mut spath = rtp.clone();
|
||||
spath.push("store");
|
||||
spath
|
||||
});
|
||||
}, PathBuf::from);
|
||||
|
||||
let cfg = Configuration::new(&rtp);
|
||||
let cfg = if cfg.is_err() {
|
||||
|
@ -87,9 +85,9 @@ impl<'a> Runtime<'a> {
|
|||
};
|
||||
|
||||
let store_config = {
|
||||
match &cfg {
|
||||
&Some(ref c) => c.store_config().map(|c| c.clone()),
|
||||
&None => None,
|
||||
match cfg {
|
||||
Some(ref c) => c.store_config().cloned(),
|
||||
None => None,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -268,8 +266,8 @@ impl<'a> Runtime<'a> {
|
|||
.value_of("editor")
|
||||
.map(String::from)
|
||||
.or({
|
||||
match &self.configuration {
|
||||
&Some(ref c) => c.editor().map(|s| s.clone()),
|
||||
match self.configuration {
|
||||
Some(ref c) => c.editor().cloned(),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
|
|
@ -51,10 +51,13 @@ pub fn config_is_valid(config: &Option<Value>) -> bool {
|
|||
|
||||
fn has_key_with_string_ary(v: &BTreeMap<String, Value>, key: &str) -> bool {
|
||||
v.get(key)
|
||||
.map(|t| match t {
|
||||
&Value::Array(ref a) => a.iter().all(|elem| {
|
||||
match elem {
|
||||
&Value::String(_) => true,
|
||||
.map_or_else(|| {
|
||||
write!(stderr(), "Required key '{}' is not in store config", key).ok();
|
||||
false
|
||||
}, |t| match *t {
|
||||
Value::Array(ref a) => a.iter().all(|elem| {
|
||||
match *elem {
|
||||
Value::String(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}),
|
||||
|
@ -63,9 +66,6 @@ pub fn config_is_valid(config: &Option<Value>) -> bool {
|
|||
.ok();
|
||||
false
|
||||
}
|
||||
}).unwrap_or_else(|| {
|
||||
write!(stderr(), "Required key '{}' is not in store config", key).ok();
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -84,18 +84,21 @@ pub fn config_is_valid(config: &Option<Value>) -> bool {
|
|||
where F: Fn(&Value) -> bool
|
||||
{
|
||||
store_config.get(section) // The store config has the section `section`
|
||||
.map(|section_table| {
|
||||
match section_table { // which is
|
||||
&Value::Table(ref section_table) => // a table
|
||||
.map_or_else(|| {
|
||||
write!(stderr(), "Store config expects section '{}' to be present, but isn't.",
|
||||
section).ok();
|
||||
false
|
||||
}, |section_table| {
|
||||
match *section_table { // which is
|
||||
Value::Table(ref section_table) => // a table
|
||||
section_table
|
||||
.iter() // which has values,
|
||||
.all(|(inner_key, cfg)| { // and all of these values
|
||||
match cfg {
|
||||
&Value::Table(ref hook_config) => { // are tables
|
||||
match *cfg {
|
||||
Value::Table(ref hook_config) => { // are tables
|
||||
hook_config.get(key) // with a key
|
||||
// fullfilling this constraint
|
||||
.map(|hook_aspect| f(&hook_aspect))
|
||||
.unwrap_or(false)
|
||||
.map_or(false, |hook_aspect| f(&hook_aspect))
|
||||
},
|
||||
_ => {
|
||||
write!(stderr(), "Store config expects '{}' to be in '{}.{}', but isn't.",
|
||||
|
@ -111,16 +114,10 @@ pub fn config_is_valid(config: &Option<Value>) -> bool {
|
|||
}
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
write!(stderr(), "Store config expects section '{}' to be present, but isn't.",
|
||||
section).ok();
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
match config {
|
||||
&Some(Value::Table(ref t)) => {
|
||||
has_key_with_string_ary(t, "pre-create-hook-aspects") &&
|
||||
match *config {
|
||||
Some(Value::Table(ref t)) => { has_key_with_string_ary(t, "pre-create-hook-aspects") &&
|
||||
has_key_with_string_ary(t, "post-create-hook-aspects") &&
|
||||
has_key_with_string_ary(t, "pre-retrieve-hook-aspects") &&
|
||||
has_key_with_string_ary(t, "post-retrieve-hook-aspects") &&
|
||||
|
@ -132,15 +129,13 @@ pub fn config_is_valid(config: &Option<Value>) -> bool {
|
|||
// The section "hooks" has maps which have a key "aspect" which has a value of type
|
||||
// String
|
||||
check_all_inner_maps_have_key_with(t, "hooks", "aspect", |asp| {
|
||||
let res = match asp { &Value::String(_) => true, _ => false };
|
||||
res
|
||||
match *asp { Value::String(_) => true, _ => false }
|
||||
}) &&
|
||||
|
||||
// The section "aspects" has maps which have a key "parllel" which has a value of type
|
||||
// Boolean
|
||||
check_all_inner_maps_have_key_with(t, "aspects", "parallel", |asp| {
|
||||
let res = match asp { &Value::Boolean(_) => true, _ => false, };
|
||||
res
|
||||
match *asp { Value::Boolean(_) => true, _ => false, }
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
|
@ -199,16 +194,15 @@ impl AspectConfig {
|
|||
}
|
||||
|
||||
fn is_parallel(init: &Value) -> bool {
|
||||
match init {
|
||||
&Value::Table(ref t) =>
|
||||
match *init {
|
||||
Value::Table(ref t) =>
|
||||
t.get("parallel")
|
||||
.map(|value| {
|
||||
match value {
|
||||
&Value::Boolean(b) => b,
|
||||
.map_or(false, |value| {
|
||||
match *value {
|
||||
Value::Boolean(b) => b,
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.unwrap_or(false),
|
||||
}),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -219,8 +213,8 @@ impl AspectConfig {
|
|||
///
|
||||
/// Returns `None` if one of the keys in the chain is not available
|
||||
pub fn get_for(v: &Option<Value>, a_name: String) -> Option<AspectConfig> {
|
||||
match v {
|
||||
&Some(Value::Table(ref tabl)) => tabl.get(&a_name[..])
|
||||
match *v {
|
||||
Some(Value::Table(ref tabl)) => tabl.get(&a_name[..])
|
||||
.map(|asp| AspectConfig::new(asp.clone())),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -231,13 +225,13 @@ impl AspectConfig {
|
|||
fn get_aspect_names_for_aspect_position(config_name: &'static str, value: &Option<Value>) -> Vec<String> {
|
||||
let mut v = vec![];
|
||||
|
||||
match value {
|
||||
&Some(Value::Table(ref t)) => {
|
||||
match *value {
|
||||
Some(Value::Table(ref t)) => {
|
||||
match t.get(config_name) {
|
||||
Some(&Value::Array(ref a)) => {
|
||||
for elem in a {
|
||||
match elem {
|
||||
&Value::String(ref s) => v.push(s.clone()),
|
||||
match *elem {
|
||||
Value::String(ref s) => v.push(s.clone()),
|
||||
_ => warn!("Non-String in configuration, inside '{}'", config_name),
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +239,7 @@ fn get_aspect_names_for_aspect_position(config_name: &'static str, value: &Optio
|
|||
_ => warn!("'{}' configuration key should contain Array, does not", config_name),
|
||||
};
|
||||
},
|
||||
&None => warn!("No store configuration"),
|
||||
None => warn!("No store configuration"),
|
||||
_ => warn!("Configuration is not a table"),
|
||||
}
|
||||
v
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::fmt;
|
||||
use std::convert::From;
|
||||
|
@ -41,35 +40,35 @@ pub enum StoreErrorKind {
|
|||
}
|
||||
|
||||
fn store_error_type_as_str(e: &StoreErrorKind) -> &'static str {
|
||||
match e {
|
||||
&StoreErrorKind::ConfigurationError => "Store Configuration Error",
|
||||
&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::IoError => "File Error",
|
||||
&StoreErrorKind::StorePathExists => "Store path exists",
|
||||
&StoreErrorKind::StorePathCreate => "Store path create",
|
||||
&StoreErrorKind::LockError => "Error locking datastructure",
|
||||
&StoreErrorKind::LockPoisoned
|
||||
match *e {
|
||||
StoreErrorKind::ConfigurationError => "Store Configuration Error",
|
||||
StoreErrorKind::FileError |
|
||||
StoreErrorKind::IoError => "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 |
|
||||
StoreErrorKind::StorePathCreate => "Store path create",
|
||||
StoreErrorKind::LockError => "Error locking datastructure",
|
||||
StoreErrorKind::LockPoisoned
|
||||
=> "The internal Store Lock has been poisoned",
|
||||
&StoreErrorKind::EntryAlreadyBorrowed => "Entry is already borrowed",
|
||||
&StoreErrorKind::EntryAlreadyExists => "Entry already exists",
|
||||
&StoreErrorKind::MalformedEntry => "Entry has invalid formatting, missing header",
|
||||
&StoreErrorKind::HeaderPathSyntaxError => "Syntax error in accessor string",
|
||||
&StoreErrorKind::HeaderPathTypeFailure => "Header has wrong type for path",
|
||||
&StoreErrorKind::HeaderKeyNotFound => "Header Key not found",
|
||||
&StoreErrorKind::HeaderTypeFailure => "Header type is wrong",
|
||||
&StoreErrorKind::HookRegisterError => "Hook register error",
|
||||
&StoreErrorKind::AspectNameNotFoundError => "Aspect name not found",
|
||||
&StoreErrorKind::HookExecutionError => "Hook execution error",
|
||||
&StoreErrorKind::PreHookExecuteError => "Pre-Hook execution error",
|
||||
&StoreErrorKind::PostHookExecuteError => "Post-Hook execution error",
|
||||
&StoreErrorKind::StorePathLacksVersion => "The supplied store path has no version part",
|
||||
&StoreErrorKind::GlobError => "glob() error",
|
||||
&StoreErrorKind::EncodingError => "Encoding error",
|
||||
StoreErrorKind::EntryAlreadyBorrowed => "Entry is already borrowed",
|
||||
StoreErrorKind::EntryAlreadyExists => "Entry already exists",
|
||||
StoreErrorKind::MalformedEntry => "Entry has invalid formatting, missing header",
|
||||
StoreErrorKind::HeaderPathSyntaxError => "Syntax error in accessor string",
|
||||
StoreErrorKind::HeaderPathTypeFailure => "Header has wrong type for path",
|
||||
StoreErrorKind::HeaderKeyNotFound => "Header Key not found",
|
||||
StoreErrorKind::HeaderTypeFailure => "Header type is wrong",
|
||||
StoreErrorKind::HookRegisterError => "Hook register error",
|
||||
StoreErrorKind::AspectNameNotFoundError => "Aspect name not found",
|
||||
StoreErrorKind::HookExecutionError => "Hook execution error",
|
||||
StoreErrorKind::PreHookExecuteError => "Pre-Hook execution error",
|
||||
StoreErrorKind::PostHookExecuteError => "Post-Hook execution error",
|
||||
StoreErrorKind::StorePathLacksVersion => "The supplied store path has no version part",
|
||||
StoreErrorKind::GlobError => "glob() error",
|
||||
StoreErrorKind::EncodingError => "Encoding error",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +108,7 @@ impl StoreError {
|
|||
* Get the error type of this StoreError
|
||||
*/
|
||||
pub fn err_type(&self) -> StoreErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -117,7 +116,7 @@ impl StoreError {
|
|||
impl Display for StoreError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", store_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", store_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -126,7 +125,7 @@ impl Display for StoreError {
|
|||
impl Error for StoreError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
store_error_type_as_str(&self.err_type.clone())
|
||||
store_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -41,7 +41,7 @@ impl StoreIdAccessor for Aspect {
|
|||
use crossbeam;
|
||||
|
||||
let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();
|
||||
if !accessors.iter().all(|a| match a { &HDA::StoreIdAccess(_) => true, _ => false }) {
|
||||
if !accessors.iter().all(|a| match *a { HDA::StoreIdAccess(_) => true, _ => false }) {
|
||||
return Err(HE::new(HEK::AccessTypeViolation, None));
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,8 @@ impl StoreIdAccessor for Aspect {
|
|||
.map(|accessor| {
|
||||
crossbeam::scope(|scope| {
|
||||
scope.spawn(|| {
|
||||
match accessor {
|
||||
&HDA::StoreIdAccess(accessor) => accessor.access(id),
|
||||
match *accessor {
|
||||
HDA::StoreIdAccess(accessor) => accessor.access(id),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.map_err(|_| ()) // TODO: We're losing the error cause here
|
||||
|
@ -76,9 +76,9 @@ impl MutableHookDataAccessor for Aspect {
|
|||
let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();
|
||||
|
||||
fn is_file_accessor(a: &HDA) -> bool {
|
||||
match a {
|
||||
&HDA::MutableAccess(_) => true,
|
||||
&HDA::NonMutableAccess(_) => true,
|
||||
match *a {
|
||||
HDA::MutableAccess(_) |
|
||||
HDA::NonMutableAccess(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ impl NonMutableHookDataAccessor for Aspect {
|
|||
use crossbeam;
|
||||
|
||||
let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();
|
||||
if !accessors.iter().all(|a| match a { &HDA::NonMutableAccess(_) => true, _ => false }) {
|
||||
if !accessors.iter().all(|a| match *a { HDA::NonMutableAccess(_) => true, _ => false }) {
|
||||
return Err(HE::new(HEK::AccessTypeViolation, None));
|
||||
}
|
||||
|
||||
|
@ -117,8 +117,8 @@ impl NonMutableHookDataAccessor for Aspect {
|
|||
.map(|accessor| {
|
||||
crossbeam::scope(|scope| {
|
||||
scope.spawn(|| {
|
||||
match accessor {
|
||||
&HDA::NonMutableAccess(accessor) => accessor.access(fle),
|
||||
match *accessor {
|
||||
HDA::NonMutableAccess(accessor) => accessor.access(fle),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.map_err(|_| ()) // TODO: We're losing the error cause here
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::clone::Clone;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::convert::Into;
|
||||
|
||||
|
@ -35,9 +34,9 @@ impl Into<HookError> for (HookErrorKind, Box<Error>) {
|
|||
}
|
||||
|
||||
fn hook_error_type_as_str(e: &HookErrorKind) -> &'static str {
|
||||
match e {
|
||||
&HookErrorKind::HookExecutionError => "Hook exec error",
|
||||
&HookErrorKind::AccessTypeViolation => "Hook access type violation",
|
||||
match *e {
|
||||
HookErrorKind::HookExecutionError => "Hook exec error",
|
||||
HookErrorKind::AccessTypeViolation => "Hook access type violation",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +76,7 @@ impl HookError {
|
|||
* Get the error type of this HookError
|
||||
*/
|
||||
pub fn err_type(&self) -> HookErrorKind {
|
||||
self.err_type.clone()
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,7 +84,7 @@ impl HookError {
|
|||
impl Display for HookError {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", hook_error_type_as_str(&self.err_type.clone())));
|
||||
try!(write!(fmt, "[{}]", hook_error_type_as_str(&self.err_type)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -94,7 +93,7 @@ impl Display for HookError {
|
|||
impl Error for HookError {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
hook_error_type_as_str(&self.err_type.clone())
|
||||
hook_error_type_as_str(&self.err_type)
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
|
@ -4,11 +4,9 @@ use std::io::{Seek, SeekFrom};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::fs::{File, OpenOptions, create_dir_all};
|
||||
|
||||
/**
|
||||
* LazyFile type
|
||||
*
|
||||
* A lazy file is either absent, but a path to it is available, or it is present.
|
||||
*/
|
||||
/// `LazyFile` type
|
||||
///
|
||||
/// A lazy file is either absent, but a path to it is available, or it is present.
|
||||
#[derive(Debug)]
|
||||
pub enum LazyFile {
|
||||
Absent(PathBuf),
|
||||
|
|
|
@ -7,7 +7,6 @@ use std::sync::Arc;
|
|||
use std::sync::RwLock;
|
||||
use std::collections::BTreeMap;
|
||||
use std::io::{Seek, SeekFrom};
|
||||
use std::io::Write;
|
||||
use std::convert::From;
|
||||
use std::convert::Into;
|
||||
use std::sync::Mutex;
|
||||
|
@ -30,7 +29,6 @@ use lazyfile::LazyFile;
|
|||
|
||||
use hook::aspect::Aspect;
|
||||
use hook::accessor::{ MutableHookDataAccessor,
|
||||
NonMutableHookDataAccessor,
|
||||
StoreIdAccessor};
|
||||
use hook::position::HookPosition;
|
||||
use hook::Hook;
|
||||
|
@ -140,7 +138,7 @@ impl StoreEntry {
|
|||
entry
|
||||
}
|
||||
} else {
|
||||
return Err(StoreError::new(StoreErrorKind::EntryAlreadyBorrowed, None))
|
||||
Err(StoreError::new(StoreErrorKind::EntryAlreadyBorrowed, None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,12 +211,10 @@ impl Store {
|
|||
return Err(StoreError::new(StoreErrorKind::StorePathCreate,
|
||||
Some(Box::new(c.unwrap_err()))));
|
||||
}
|
||||
} else {
|
||||
if location.is_file() {
|
||||
} else if location.is_file() {
|
||||
debug!("Store path exists as file");
|
||||
return Err(StoreError::new(StoreErrorKind::StorePathExists, None));
|
||||
}
|
||||
}
|
||||
|
||||
let pre_create_aspects = get_pre_create_aspect_names(&store_config)
|
||||
.into_iter().map(|n| {
|
||||
|
@ -468,7 +464,7 @@ impl Store {
|
|||
|
||||
pub fn register_hook(&mut self,
|
||||
position: HookPosition,
|
||||
aspect_name: &String,
|
||||
aspect_name: &str,
|
||||
mut h: Box<Hook>)
|
||||
-> Result<()>
|
||||
{
|
||||
|
@ -506,16 +502,16 @@ impl Store {
|
|||
}
|
||||
|
||||
let annfe = StoreError::new(StoreErrorKind::AspectNameNotFoundError, None);
|
||||
return Err(StoreError::new(StoreErrorKind::HookRegisterError, Some(Box::new(annfe))));
|
||||
Err(StoreError::new(StoreErrorKind::HookRegisterError, Some(Box::new(annfe))))
|
||||
}
|
||||
|
||||
fn get_config_for_hook(&self, name: &str) -> Option<&Value> {
|
||||
match &self.configuration {
|
||||
&Some(Value::Table(ref tabl)) => {
|
||||
match self.configuration {
|
||||
Some(Value::Table(ref tabl)) => {
|
||||
tabl.get("hooks")
|
||||
.map(|hook_section| {
|
||||
match hook_section {
|
||||
&Value::Table(ref tabl) => tabl.get(name),
|
||||
match *hook_section {
|
||||
Value::Table(ref tabl) => tabl.get(name),
|
||||
_ => None
|
||||
}
|
||||
})
|
||||
|
@ -635,17 +631,13 @@ impl<'a> Drop for FileLockEntry<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* EntryContent type
|
||||
*/
|
||||
/// `EntryContent` type
|
||||
pub type EntryContent = String;
|
||||
|
||||
/**
|
||||
* EntryHeader
|
||||
*
|
||||
* This is basically a wrapper around toml::Table which provides convenience to the user of the
|
||||
* librray.
|
||||
*/
|
||||
/// `EntryHeader`
|
||||
///
|
||||
/// This is basically a wrapper around `toml::Table` which provides convenience to the user of the
|
||||
/// library.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EntryHeader {
|
||||
header: Value,
|
||||
|
@ -691,8 +683,8 @@ impl EntryHeader {
|
|||
}
|
||||
|
||||
pub fn verify(&self) -> Result<()> {
|
||||
match &self.header {
|
||||
&Value::Table(ref t) => verify_header(&t),
|
||||
match self.header {
|
||||
Value::Table(ref t) => verify_header(&t),
|
||||
_ => Err(StoreError::new(StoreErrorKind::HeaderTypeFailure, None)),
|
||||
}
|
||||
}
|
||||
|
@ -751,13 +743,13 @@ impl EntryHeader {
|
|||
return Ok(false);
|
||||
}
|
||||
|
||||
match destination {
|
||||
&Token::Key(ref s) => { // if the destination shall be an map key
|
||||
match value {
|
||||
match *destination {
|
||||
Token::Key(ref s) => { // if the destination shall be an map key
|
||||
match *value {
|
||||
/*
|
||||
* Put it in there if we have a map
|
||||
*/
|
||||
&mut Value::Table(ref mut t) => {
|
||||
Value::Table(ref mut t) => {
|
||||
t.insert(s.clone(), v);
|
||||
}
|
||||
|
||||
|
@ -768,13 +760,13 @@ impl EntryHeader {
|
|||
}
|
||||
},
|
||||
|
||||
&Token::Index(i) => { // if the destination shall be an array
|
||||
match value {
|
||||
Token::Index(i) => { // if the destination shall be an array
|
||||
match *value {
|
||||
|
||||
/*
|
||||
* Put it in there if we have an array
|
||||
*/
|
||||
&mut Value::Array(ref mut a) => {
|
||||
Value::Array(ref mut a) => {
|
||||
a.push(v); // push to the end of the array
|
||||
|
||||
// if the index is inside the array, we swap-remove the element at this
|
||||
|
@ -845,13 +837,13 @@ impl EntryHeader {
|
|||
let mut value = value.unwrap();
|
||||
debug!("walked value = {:?}", value);
|
||||
|
||||
match destination {
|
||||
&Token::Key(ref s) => { // if the destination shall be an map key->value
|
||||
match value {
|
||||
match *destination {
|
||||
Token::Key(ref s) => { // if the destination shall be an map key->value
|
||||
match *value {
|
||||
/*
|
||||
* Put it in there if we have a map
|
||||
*/
|
||||
&mut Value::Table(ref mut t) => {
|
||||
Value::Table(ref mut t) => {
|
||||
debug!("Matched Key->Table");
|
||||
return Ok(t.insert(s.clone(), v));
|
||||
}
|
||||
|
@ -866,13 +858,13 @@ impl EntryHeader {
|
|||
}
|
||||
},
|
||||
|
||||
&Token::Index(i) => { // if the destination shall be an array
|
||||
match value {
|
||||
Token::Index(i) => { // if the destination shall be an array
|
||||
match *value {
|
||||
|
||||
/*
|
||||
* Put it in there if we have an array
|
||||
*/
|
||||
&mut Value::Array(ref mut a) => {
|
||||
Value::Array(ref mut a) => {
|
||||
debug!("Matched Index->Array");
|
||||
a.push(v); // push to the end of the array
|
||||
|
||||
|
@ -971,10 +963,10 @@ impl EntryHeader {
|
|||
let mut value = value.unwrap();
|
||||
debug!("walked value = {:?}", value);
|
||||
|
||||
match destination {
|
||||
&Token::Key(ref s) => { // if the destination shall be an map key->value
|
||||
match value {
|
||||
&mut Value::Table(ref mut t) => {
|
||||
match *destination {
|
||||
Token::Key(ref s) => { // if the destination shall be an map key->value
|
||||
match *value {
|
||||
Value::Table(ref mut t) => {
|
||||
debug!("Matched Key->Table, removing {:?}", s);
|
||||
return Ok(t.remove(s));
|
||||
},
|
||||
|
@ -985,9 +977,9 @@ impl EntryHeader {
|
|||
}
|
||||
},
|
||||
|
||||
&Token::Index(i) => { // if the destination shall be an array
|
||||
match value {
|
||||
&mut Value::Array(ref mut a) => {
|
||||
Token::Index(i) => { // if the destination shall be an array
|
||||
match *value {
|
||||
Value::Array(ref mut a) => {
|
||||
// if the index is inside the array, we swap-remove the element at this
|
||||
// index
|
||||
if a.len() > i {
|
||||
|
@ -1037,9 +1029,9 @@ impl EntryHeader {
|
|||
walk_iter(Ok(v), &mut tokens.into_iter())
|
||||
}
|
||||
|
||||
fn extract_from_table<'a>(v: &'a mut Value, s: &String) -> Result<&'a mut Value> {
|
||||
match v {
|
||||
&mut Value::Table(ref mut t) => {
|
||||
fn extract_from_table<'a>(v: &'a mut Value, s: &str) -> Result<&'a mut Value> {
|
||||
match *v {
|
||||
Value::Table(ref mut t) => {
|
||||
t.get_mut(&s[..])
|
||||
.ok_or(StoreError::new(StoreErrorKind::HeaderKeyNotFound, None))
|
||||
},
|
||||
|
@ -1048,8 +1040,8 @@ impl EntryHeader {
|
|||
}
|
||||
|
||||
fn extract_from_array(v: &mut Value, i: usize) -> Result<&mut Value> {
|
||||
match v {
|
||||
&mut Value::Array(ref mut a) => {
|
||||
match *v {
|
||||
Value::Array(ref mut a) => {
|
||||
if a.len() < i {
|
||||
Err(StoreError::new(StoreErrorKind::HeaderKeyNotFound, None))
|
||||
} else {
|
||||
|
@ -1061,9 +1053,9 @@ impl EntryHeader {
|
|||
}
|
||||
|
||||
fn extract<'a>(v: &'a mut Value, token: &Token) -> Result<&'a mut Value> {
|
||||
match token {
|
||||
&Token::Key(ref s) => EntryHeader::extract_from_table(v, s),
|
||||
&Token::Index(i) => EntryHeader::extract_from_array(v, i),
|
||||
match *token {
|
||||
Token::Key(ref s) => EntryHeader::extract_from_table(v, s),
|
||||
Token::Index(i) => EntryHeader::extract_from_array(v, i),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1125,7 +1117,7 @@ fn verify_header_consistency(t: Table) -> EntryResult<Table> {
|
|||
|
||||
fn has_only_tables(t: &Table) -> bool {
|
||||
debug!("Verifying that table has only tables");
|
||||
t.iter().all(|(_, x)| if let &Value::Table(_) = x { true } else { false })
|
||||
t.iter().all(|(_, x)| if let Value::Table(_) = *x { true } else { false })
|
||||
}
|
||||
|
||||
fn has_main_section(t: &Table) -> bool {
|
||||
|
@ -1140,12 +1132,12 @@ fn has_main_section(t: &Table) -> bool {
|
|||
fn has_imag_version_in_main_section(t: &Table) -> bool {
|
||||
use semver::Version;
|
||||
|
||||
match t.get("imag").unwrap() {
|
||||
&Value::Table(ref sec) => {
|
||||
match *t.get("imag").unwrap() {
|
||||
Value::Table(ref sec) => {
|
||||
sec.get("version")
|
||||
.and_then(|v| {
|
||||
match v {
|
||||
&Value::String(ref s) => {
|
||||
match *v {
|
||||
Value::String(ref s) => {
|
||||
Some(Version::parse(&s[..]).is_ok())
|
||||
},
|
||||
_ => Some(false),
|
||||
|
|
|
@ -85,7 +85,7 @@ impl IntoStoreId for StoreId {
|
|||
|
||||
pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
|
||||
debug!("Checking path element for version");
|
||||
if path_elem.split("~").last().map(|v| Version::parse(v).is_err()).unwrap_or(false) {
|
||||
if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
|
||||
debug!("Version cannot be parsed from {:?}", path_elem);
|
||||
debug!("Path does not contain version!");
|
||||
return Err(StoreError::new(StoreErrorKind::StorePathLacksVersion, None));
|
||||
|
@ -95,8 +95,8 @@ pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
|
|||
debug!("Building path from {:?}", path_elem);
|
||||
let mut path = store.path().clone();
|
||||
|
||||
if path_elem.chars().next() == Some('/') {
|
||||
path.push(&path_elem[1..path_elem.len()]);
|
||||
if path_elem.starts_with('/') {
|
||||
path.push(&path_elem[1..]);
|
||||
} else {
|
||||
path.push(path_elem);
|
||||
}
|
||||
|
|
|
@ -43,14 +43,14 @@ impl HookDataAccessorProvider for DebugHook {
|
|||
use libimagstore::hook::accessor::HookDataAccessor as HDA;
|
||||
|
||||
match self.position {
|
||||
HP::PreCreate => HDA::StoreIdAccess(&self.accessor),
|
||||
HP::PostCreate => HDA::MutableAccess(&self.accessor),
|
||||
HP::PreRetrieve => HDA::StoreIdAccess(&self.accessor),
|
||||
HP::PostRetrieve => HDA::MutableAccess(&self.accessor),
|
||||
HP::PreUpdate => HDA::MutableAccess(&self.accessor),
|
||||
HP::PostUpdate => HDA::MutableAccess(&self.accessor),
|
||||
HP::PreDelete => HDA::StoreIdAccess(&self.accessor),
|
||||
HP::PreCreate |
|
||||
HP::PreRetrieve |
|
||||
HP::PreDelete |
|
||||
HP::PostDelete => HDA::StoreIdAccess(&self.accessor),
|
||||
HP::PostCreate |
|
||||
HP::PostRetrieve |
|
||||
HP::PreUpdate |
|
||||
HP::PostUpdate => HDA::MutableAccess(&self.accessor),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,9 +51,9 @@ pub enum Action {
|
|||
}
|
||||
|
||||
fn action_to_str(a: &Action) -> &'static str {
|
||||
match a {
|
||||
&Action::Lock => "lock",
|
||||
&Action::Unlock => "unlock",
|
||||
match *a {
|
||||
Action::Lock => "lock",
|
||||
Action::Unlock => "unlock",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,12 +57,10 @@ impl NonMutableHookDataAccessor for LinkedEntriesExistHook {
|
|||
path.push(link);
|
||||
if !path.exists() {
|
||||
warn!("File link does not exist: {:?} -> {:?}", fle.get_location(), path);
|
||||
} else {
|
||||
if !path.is_file() {
|
||||
} else if !path.is_file() {
|
||||
warn!("File link is not a file: {:?} -> {:?}", fle.get_location(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.map_err(|e| {
|
||||
warn!("Couldn't execute Link-Verify hook");
|
||||
|
|
|
@ -59,7 +59,7 @@ fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
|
|||
e.cause()
|
||||
}
|
||||
|
||||
/// Count errors in Error::cause() recursively
|
||||
/// Count errors in `Error::cause()` recursively
|
||||
fn count_error_causes(e: &Error) -> u64 {
|
||||
1 + if e.cause().is_some() { count_error_causes(e.cause().unwrap()) } else { 0 }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue