summaryrefslogtreecommitdiffstats
path: root/lib/core/libimagstore/src/store.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/core/libimagstore/src/store.rs')
-rw-r--r--lib/core/libimagstore/src/store.rs134
1 files changed, 64 insertions, 70 deletions
diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs
index e5748121..79eb5b3e 100644
--- a/lib/core/libimagstore/src/store.rs
+++ b/lib/core/libimagstore/src/store.rs
@@ -30,15 +30,15 @@ use std::fmt::Formatter;
use std::fmt::Debug;
use std::fmt::Error as FMTError;
-use libimagerror::errors::ErrorMsg as EM;
+use libimagerror::errors::Error as EM;
use toml::Value;
use toml_query::read::TomlValueReadExt;
use toml_query::read::TomlValueReadTypeExt;
-use failure::Fallible as Result;
-use failure::ResultExt;
-use failure::err_msg;
-use failure::Error;
+use anyhow::Result;
+use anyhow::Context;
+
+use anyhow::Error;
use crate::storeid::{IntoStoreId, StoreId};
use crate::iter::Entries;
@@ -70,9 +70,7 @@ impl StoreEntry {
#[cfg(feature = "fs-lock")]
{
- open_file(pb.clone())
- .and_then(|f| f.lock_exclusive())
- .with_context(|| EM::IO)?;
+ open_file(pb.clone()).and_then(|f| f.lock_exclusive())?;
}
Ok(StoreEntry {
@@ -96,7 +94,7 @@ impl StoreEntry {
None => Ok(Entry::new(self.id.clone()))
}
} else {
- Err(format_err!("EntryAlreadyBorrowed: {}", self.id))
+ Err(anyhow!("EntryAlreadyBorrowed: {}", self.id))
}
}
@@ -188,18 +186,15 @@ impl Store {
debug!("Building new Store object");
if !location.exists() {
if !config_implicit_store_create_allowed(store_config)? {
- return Err(format_err!("CreateStoreDirDenied"))
- .context(EM::FileError)
- .context(EM::IO)
- .map_err(Error::from)
+ return Err(anyhow!("CreateStoreDirDenied"));
}
backend
.create_dir_all(&location)
- .context(format_err!("StorePathCreate: {}", location.display()))?;
+ .context(anyhow!("StorePathCreate: {}", location.display()))?;
} else if location.is_file() {
debug!("Store path exists as file");
- return Err(format_err!("StorePathExists: {}", location.display()));
+ return Err(anyhow!("StorePathExists: {}", location.display()));
}
let store = Store {
@@ -222,8 +217,8 @@ impl Store {
self.entries
.read()
- .map_err(|_| Error::from(EM::LockError))
- .context(format_err!("Error while checking whether {} is borrowed", id))
+ .map_err(|_| EM::LockError)
+ .context(anyhow!("Error while checking whether {} is borrowed", id))
.map(|cache| cache.get(&id).map(|e| e.is_borrowed()).unwrap_or(false))
.map_err(Error::from)
}
@@ -243,20 +238,20 @@ impl Store {
if exists {
debug!("Entry exists: {:?}", id);
- return Err(format_err!("EntryAlreadyExists: {}", id));
+ return Err(anyhow!("EntryAlreadyExists: {}", id));
}
{
let mut hsmap = self
.entries
.write()
- .map_err(|_| Error::from(EM::LockError))
- .context(format_err!("CreateCallError: {}", id))?;
+ .map_err(|_| EM::LockError)
+ .context(anyhow!("CreateCallError: {}", id))?;
if hsmap.contains_key(&id) {
debug!("Cannot create, internal cache already contains: '{}'", id);
- return Err(format_err!("EntryAlreadyExists: {}", id))
- .context(format_err!("CreateCallError: {}", id))
+ return Err(anyhow!("EntryAlreadyExists: {}", id))
+ .context(anyhow!("CreateCallError: {}", id))
.map_err(Error::from)
}
hsmap.insert(id.clone(), {
@@ -288,7 +283,8 @@ impl Store {
let entry = self
.entries
.write()
- .map_err(|_| Error::from(EM::LockError))
+ .map_err(|_| EM::LockError)
+ .map_err(Error::from)
.and_then(|mut es| {
let new_se = StoreEntry::new(self.path().clone(), id.clone(), &self.backend)?;
let se = es.entry(id.clone()).or_insert(new_se);
@@ -296,7 +292,7 @@ impl Store {
se.status = StoreEntryStatus::Borrowed;
entry
})
- .context(format_err!("RetrieveCallError: {}", id))?;
+ .context(anyhow!("RetrieveCallError: {}", id))?;
debug!("Constructing FileLockEntry: '{}'", id);
Ok(FileLockEntry::new(self, entry))
@@ -326,7 +322,7 @@ impl Store {
self.retrieve(id.clone())
.map(Some)
- .context(format_err!("GetCallError: {}", id))
+ .context(anyhow!("GetCallError: {}", id))
.map_err(Error::from)
}
@@ -339,7 +335,7 @@ impl Store {
pub fn update<'a>(&'a self, entry: &mut FileLockEntry<'a>) -> Result<()> {
debug!("Updating FileLockEntry at '{}'", entry.get_location());
self._update(entry, false)
- .context(format_err!("UpdateCallError: {}", entry.get_location()))
+ .context(anyhow!("UpdateCallError: {}", entry.get_location()))
.map_err(Error::from)
}
@@ -351,8 +347,7 @@ impl Store {
/// it is not public.
///
fn _update<'a>(&'a self, entry: &mut FileLockEntry<'a>, modify_presence: bool) -> Result<()> {
- let mut hsmap = self.entries.write()
- .map_err(|_| Error::from(EM::LockError))?;
+ let mut hsmap = self.entries.write().map_err(|_| EM::LockError)?;
let se = hsmap.get_mut(&entry.location).ok_or_else(|| {
EM::EntryNotFound(entry.location.local_display_string())
@@ -388,8 +383,7 @@ impl Store {
pub fn flush_cache(&self) -> Result<()> {
// We borrow this early so that between the aggregation of the flushables and the actual
// flush, there is no borrowing from the store.
- let mut hsmap = self.entries.write()
- .map_err(|_| Error::from(EM::LockError))?;
+ let mut hsmap = self.entries.write().map_err(|_| EM::LockError)?;
let mut to_flush = vec![];
for (storeid, se) in hsmap.deref() {
@@ -409,13 +403,17 @@ impl Store {
/// The number of elements in the internal cache
pub fn cache_size(&self) -> Result<usize> {
- let hsmap = self.entries.read().map_err(|_| Error::from(EM::LockError))?;
+ let hsmap = self.entries
+ .read()
+ .map_err(|_| EM::LockError)?;
Ok(hsmap.iter().count())
}
/// The size of the internal cache
pub fn cache_capacity(&self) -> Result<usize> {
- let hsmap = self.entries.read().map_err(|_| Error::from(EM::LockError))?;
+ let hsmap = self.entries
+ .read()
+ .map_err(|_| EM::LockError)?;
Ok(hsmap.capacity())
}
@@ -428,14 +426,15 @@ impl Store {
pub fn get_copy<S: IntoStoreId>(&self, id: S) -> Result<Entry> {
let id = id.into_storeid()?;
debug!("Retrieving copy of '{}'", id);
- let entries = self.entries.write()
- .map_err(|_| Error::from(EM::LockError))
- .context(format_err!("RetrieveCopyCallError: {}", id))?;
+ let entries = self.entries
+ .write()
+ .map_err(|_| EM::LockError)
+ .context(anyhow!("RetrieveCopyCallError: {}", id))?;
// if the entry is currently modified by the user, we cannot drop it
if entries.get(&id).map(|e| e.is_borrowed()).unwrap_or(false) {
return Err(EM::IdLocked)
- .context(format_err!("RetrieveCopyCallError: {}", id))
+ .context(anyhow!("RetrieveCopyCallError: {}", id))
.map_err(Error::from)
}
@@ -463,13 +462,13 @@ impl Store {
let mut entries = self
.entries
.write()
- .map_err(|_| Error::from(EM::LockError))
- .context(format_err!("DeleteCallError: {}", id))?;
+ .map_err(|_| EM::LockError)
+ .context(anyhow!("DeleteCallError: {}", id))?;
let do_remove = match entries.get(&id) {
Some(e) => if e.is_borrowed() { // entry is currently borrowed, we cannot delete it
return Err(Error::from(EM::LockError))
- .context(format_err!("DeleteCallError: {}", id))
+ .context(anyhow!("DeleteCallError: {}", id))
.map_err(Error::from)
// false
} else { // Entry is in the cache
@@ -484,7 +483,7 @@ impl Store {
if !self.backend.exists(&pb)? {
debug!("Seems like {:?} is not even on the FS", pb);
return Err(EM::FileNotFound)
- .context(format_err!("DeleteCallError: {}", id))
+ .context(anyhow!("DeleteCallError: {}", id))
.map_err(Error::from)
} // else { continue }
@@ -501,8 +500,8 @@ impl Store {
self
.backend
.remove_file(&pb)
- .context(EM::FileError)
- .context(format_err!("DeleteCallError: {}", id))?;
+ .map_err(Error::from)
+ .context(anyhow!("DeleteCallError: {}", id))?;
debug!("Deleted");
Ok(())
@@ -527,12 +526,12 @@ impl Store {
let hsmap = self
.entries
.write()
- .map_err(|_| Error::from(EM::LockError))
- .context(format_err!("MoveCallError: {} -> {}", entry.get_location(), new_id))?;
+ .map_err(|_| EM::LockError)
+ .context(anyhow!("MoveCallError: {} -> {}", entry.get_location(), new_id))?;
if hsmap.contains_key(&new_id) {
- return Err(format_err!("Entry exists already: {}", new_id.clone()))
- .context(format_err!("MoveCallError: {} -> {}", entry.get_location(), new_id))
+ return Err(anyhow!("Entry exists already: {}", new_id.clone()))
+ .context(anyhow!("MoveCallError: {} -> {}", entry.get_location(), new_id))
.map_err(Error::from)
}
@@ -548,8 +547,7 @@ impl Store {
} else {
Ok(())
})
- .context(EM::FileError)
- .context(format_err!("MoveCallError: {} -> {}", old_id, new_id))
+ .context(anyhow!("MoveCallError: {} -> {}", old_id, new_id))
.map_err(Error::from)
}
@@ -591,10 +589,10 @@ impl Store {
{
let mut hsmap = self.entries.write()
- .map_err(|_| Error::from(EM::LockError))?;
+ .map_err(|_| EM::LockError)?;
if hsmap.contains_key(&new_id) {
- return Err(format_err!("Entry already exists: {}", new_id));
+ return Err(anyhow!("Entry already exists: {}", new_id));
}
debug!("New id does not exist in cache");
@@ -602,7 +600,7 @@ impl Store {
let new_id_pb = new_id.clone().with_base(self.path()).into_pathbuf()?;
if !self.backend.exists(&old_id_pb)? {
- return Err(format_err!("Entry does not exist: {}", old_id));
+ return Err(anyhow!("Entry does not exist: {}", old_id));
}
// if it is borrowed, we really should not rename it, as this might
@@ -610,11 +608,11 @@ impl Store {
//
// Also, remove this object from the cache
if hsmap.remove(&old_id).map(|e| e.is_borrowed()).unwrap_or(false) {
- return Err(format_err!("Entry already borrowed: {}", old_id));
+ return Err(anyhow!("Entry already borrowed: {}", old_id));
}
if self.backend.exists(&new_id_pb)? {
- return Err(format_err!("Entry already exists: {}", new_id));
+ return Err(anyhow!("Entry already exists: {}", new_id));
}
debug!("New entry does not yet exist on filesystem. Good.");
@@ -624,7 +622,7 @@ impl Store {
.context({
let old = old_id_pb.display().to_string();
let new = new_id_pb.display().to_string();
- format_err!("Rename error: {} -> {}", old, new)
+ anyhow!("Rename error: {} -> {}", old, new)
})?;
debug!("Rename worked on filesystem");
@@ -647,9 +645,9 @@ impl Store {
let cache_has_entry = |id: &StoreId|
self.entries
.read()
+ .map_err(|_| EM::LockError)
.map(|map| map.contains_key(id))
- .map_err(|_| Error::from(EM::LockError))
- .context(format_err!("CreateCallError: {}", id));
+ .context(anyhow!("CreateCallError: {}", id));
let backend_has_entry = |id: StoreId|
self.backend.exists(&id.with_base(self.path()).into_pathbuf()?);
@@ -795,7 +793,7 @@ impl Entry {
pub fn from_reader<S: IntoStoreId>(loc: S, file: &mut dyn Read) -> Result<Entry> {
let text = {
let mut s = String::new();
- file.read_to_string(&mut s).context(EM::IO)?;
+ file.read_to_string(&mut s)?;
s
};
Self::from_str(loc, &text[..])
@@ -833,7 +831,7 @@ impl Entry {
Ok(format!("---\n{header}---\n{content}",
header = ::toml::ser::to_string_pretty(&self.header)
.map_err(Error::from)
- .context(err_msg("TOML Error"))?,
+ .context(anyhow!("TOML Error"))?,
content = self.content))
}
@@ -882,12 +880,12 @@ impl Entry {
/// Currently, this only verifies the header. This might change in the future.
pub fn verify(&self) -> Result<()> {
if !has_main_section(&self.header)? {
- Err(format_err!("MissingMainSection"))
+ Err(anyhow!("MissingMainSection"))
} else if !has_imag_version_in_main_section(&self.header)? {
- Err(format_err!("MissingVersionInfo"))
+ Err(anyhow!("MissingVersionInfo"))
} else if !has_only_tables(&self.header)? {
debug!("Could not verify that it only has tables in its base table");
- Err(format_err!("NonTableInBaseTable"))
+ Err(anyhow!("NonTableInBaseTable"))
} else {
Ok(())
}
@@ -909,23 +907,19 @@ fn has_only_tables(t: &Value) -> Result<bool> {
debug!("Verifying that table has only tables");
match *t {
Value::Table(ref tab) => Ok(tab.iter().all(|(_, x)| is_match!(*x, Value::Table(_)))),
- _ => Err(format_err!("HeaderTypeFailure")),
+ _ => Err(anyhow!("HeaderTypeFailure")),
}
}
fn has_main_section(t: &Value) -> Result<bool> {
- t.read("imag")
- .map_err(Error::from)
- .context(EM::TomlQueryError)?
- .ok_or_else(|| format_err!("ConfigKeyMissingError('imag')"))
+ t.read("imag")?
+ .ok_or_else(|| anyhow!("ConfigKeyMissingError('imag')"))
.map(Value::is_table)
}
fn has_imag_version_in_main_section(t: &Value) -> Result<bool> {
- t.read_string("imag.version")
- .map_err(Error::from)
- .context(EM::TomlQueryError)?
- .ok_or_else(|| format_err!("ConfigKeyMissingError('imag.version')"))
+ t.read_string("imag.version")?
+ .ok_or_else(|| anyhow!("ConfigKeyMissingError('imag.version')"))
.map_err(Error::from)
.map(String::from)
.map(|s: String| ::semver::Version::parse(&s).is_ok())