libimagentryref: Move from error-chain to failure
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
5a7def4c8e
commit
9b48dc27cd
7 changed files with 51 additions and 133 deletions
|
@ -23,8 +23,8 @@ maintenance = { status = "actively-developed" }
|
|||
itertools = "0.7"
|
||||
log = "0.4.0"
|
||||
toml = "0.4"
|
||||
toml-query = "0.7"
|
||||
error-chain = "0.12"
|
||||
toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" }
|
||||
failure = "0.1"
|
||||
sha-1 = { version = "0.7", optional = true }
|
||||
sha2 = { version = "0.7", optional = true }
|
||||
sha3 = { version = "0.7", optional = true }
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
//
|
||||
// imag - the personal information management suite for the commandline
|
||||
// Copyright (C) 2015-2018 Matthias Beyer <mail@beyermatthias.de> and contributors
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; version
|
||||
// 2.1 of the License.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
//
|
||||
|
||||
error_chain! {
|
||||
types {
|
||||
RefError, RefErrorKind, ResultExt, Result;
|
||||
}
|
||||
|
||||
links {
|
||||
StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind);
|
||||
TomlQueryError(::toml_query::error::Error, ::toml_query::error::ErrorKind);
|
||||
EntryUtilError(::libimagentryutil::error::EntryUtilError, ::libimagentryutil::error::EntryUtilErrorKind);
|
||||
}
|
||||
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
Utf8Error(::std::string::FromUtf8Error);
|
||||
TomlDeError(::toml::de::Error);
|
||||
TomlSerError(::toml::ser::Error);
|
||||
}
|
||||
|
||||
errors {
|
||||
HeaderTypeError(field: &'static str, expectedtype: &'static str) {
|
||||
description("Header type error")
|
||||
display("Header type error: '{}' should be {}", field, expectedtype)
|
||||
}
|
||||
|
||||
HeaderFieldMissingError(field: &'static str) {
|
||||
description("Header field missing error")
|
||||
display("Header field missing: {}", field)
|
||||
}
|
||||
|
||||
HeaderFieldWriteError {
|
||||
description("Header field cannot be written")
|
||||
display("Header field cannot be written")
|
||||
}
|
||||
|
||||
HeaderFieldReadError {
|
||||
description("Header field cannot be read")
|
||||
display("Header field cannot be read")
|
||||
}
|
||||
|
||||
HeaderFieldAlreadyExistsError {
|
||||
description("Header field already exists, cannot override")
|
||||
display("Header field already exists, cannot override")
|
||||
}
|
||||
|
||||
PathUTF8Error {
|
||||
description("Path cannot be converted because of UTF8 Error")
|
||||
display("Path cannot be converted because of UTF8 Error")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -21,27 +21,26 @@ use std::path::Path;
|
|||
|
||||
use libimagstore::storeid::StoreId;
|
||||
|
||||
use error::RefError;
|
||||
use refstore::UniqueRefPathGenerator;
|
||||
|
||||
use failure::Fallible as Result;
|
||||
|
||||
/// A base UniqueRefPathGenerator which must be overridden by the actual UniqueRefPathGenerator
|
||||
/// which is provided by this crate
|
||||
#[allow(dead_code)]
|
||||
pub struct Base;
|
||||
|
||||
impl UniqueRefPathGenerator for Base {
|
||||
type Error = RefError;
|
||||
|
||||
fn collection() -> &'static str {
|
||||
"ref"
|
||||
}
|
||||
|
||||
fn unique_hash<A: AsRef<Path>>(_path: A) -> Result<String, Self::Error> {
|
||||
fn unique_hash<A: AsRef<Path>>(_path: A) -> Result<String> {
|
||||
// This has to be overridden
|
||||
panic!("Not overridden base functionality. This is a BUG!")
|
||||
}
|
||||
|
||||
fn postprocess_storeid(sid: StoreId) -> Result<StoreId, Self::Error> {
|
||||
fn postprocess_storeid(sid: StoreId) -> Result<StoreId> {
|
||||
Ok(sid) // default implementation
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,24 +50,22 @@ macro_rules! make_unique_ref_path_generator {
|
|||
(
|
||||
$name:ident
|
||||
over $underlying:ty
|
||||
=> with error $errtype:ty
|
||||
=> with collection name $collectionname:expr
|
||||
) => {
|
||||
struct $name;
|
||||
|
||||
impl $crate::refstore::UniqueRefPathGenerator for $name {
|
||||
type Error = $errtype;
|
||||
|
||||
fn collection() -> &'static str {
|
||||
$collectionname
|
||||
}
|
||||
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> Result<String, Self::Error> {
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> Result<String> {
|
||||
$underlying::unique_hash(path)
|
||||
}
|
||||
|
||||
fn postprocess_storeid(sid: ::libimagstore::storeid::StoreId)
|
||||
-> Result<::libimagstore::storeid::StoreId, Self::Error>
|
||||
-> Result<::libimagstore::storeid::StoreId>
|
||||
{
|
||||
Ok(sid)
|
||||
}
|
||||
|
@ -77,7 +75,6 @@ macro_rules! make_unique_ref_path_generator {
|
|||
(
|
||||
$name:ident
|
||||
over $underlying:ty
|
||||
=> with error $errtype:ty
|
||||
=> with collection name $collectionname:expr
|
||||
=> $impl:expr
|
||||
) => {
|
||||
|
@ -90,13 +87,13 @@ macro_rules! make_unique_ref_path_generator {
|
|||
$collectionname
|
||||
}
|
||||
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> Result<String, Self::Error> {
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> Result<String> {
|
||||
debug!("Making unique hash for path: {:?}", path.as_ref());
|
||||
$impl(path)
|
||||
}
|
||||
|
||||
fn postprocess_storeid(sid: ::libimagstore::storeid::StoreId)
|
||||
-> Result<::libimagstore::storeid::StoreId, Self::Error>
|
||||
-> Result<::libimagstore::storeid::StoreId>
|
||||
{
|
||||
Ok(sid)
|
||||
}
|
||||
|
@ -106,14 +103,12 @@ macro_rules! make_unique_ref_path_generator {
|
|||
(
|
||||
pub $name:ident
|
||||
over $underlying:ty
|
||||
=> with error $errtype:ty
|
||||
=> with collection name $collectionname:expr
|
||||
=> $impl:expr
|
||||
) => {
|
||||
make_unique_ref_path_generator!(
|
||||
pub $name
|
||||
over $underlying
|
||||
=> with error $errtype
|
||||
=> with collection name $collectionname
|
||||
=> $impl => |sid| { Ok(sid) }
|
||||
);
|
||||
|
@ -122,7 +117,6 @@ macro_rules! make_unique_ref_path_generator {
|
|||
(
|
||||
pub $name:ident
|
||||
over $underlying:ty
|
||||
=> with error $errtype:ty
|
||||
=> with collection name $collectionname:expr
|
||||
=> $impl:expr
|
||||
=> $postproc:expr
|
||||
|
@ -130,19 +124,17 @@ macro_rules! make_unique_ref_path_generator {
|
|||
pub struct $name;
|
||||
|
||||
impl $crate::refstore::UniqueRefPathGenerator for $name {
|
||||
type Error = $errtype;
|
||||
|
||||
fn collection() -> &'static str {
|
||||
$collectionname
|
||||
}
|
||||
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> ::std::result::Result<String, Self::Error> {
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> ::failure::Fallible<String> {
|
||||
debug!("Making unique hash for path: {:?}", path.as_ref());
|
||||
$impl(path)
|
||||
}
|
||||
|
||||
fn postprocess_storeid(sid: ::libimagstore::storeid::StoreId)
|
||||
-> Result<::libimagstore::storeid::StoreId, Self::Error>
|
||||
-> ::failure::Fallible<::libimagstore::storeid::StoreId>
|
||||
{
|
||||
$postproc(sid)
|
||||
}
|
||||
|
@ -173,13 +165,10 @@ macro_rules! make_sha_mod {
|
|||
use std::fs::OpenOptions;
|
||||
use std::io::Read;
|
||||
|
||||
use error::RefError as RE;
|
||||
|
||||
use hex;
|
||||
make_unique_ref_path_generator! (
|
||||
pub $hashname
|
||||
over generators::base::Base
|
||||
=> with error RE
|
||||
=> with collection name "ref"
|
||||
=> |path| {
|
||||
OpenOptions::new()
|
||||
|
@ -187,7 +176,7 @@ macro_rules! make_sha_mod {
|
|||
.write(false)
|
||||
.create(false)
|
||||
.open(path)
|
||||
.map_err(RE::from)
|
||||
.map_err(::failure::Error::from)
|
||||
.and_then(|mut file| {
|
||||
let mut buffer = String::new();
|
||||
let _ = file.read_to_string(&mut buffer)?;
|
||||
|
@ -199,14 +188,14 @@ macro_rules! make_sha_mod {
|
|||
impl $hashname {
|
||||
|
||||
/// Function which can be used by a wrapping UniqueRefPathGenerator to hash only N bytes.
|
||||
pub fn hash_n_bytes<A: AsRef<Path>>(path: A, n: usize) -> Result<String, RE> {
|
||||
pub fn hash_n_bytes<A: AsRef<Path>>(path: A, n: usize) -> ::failure::Fallible<String> {
|
||||
debug!("Opening '{}' for hashing", path.as_ref().display());
|
||||
OpenOptions::new()
|
||||
.read(true)
|
||||
.write(false)
|
||||
.create(false)
|
||||
.open(path)
|
||||
.map_err(RE::from)
|
||||
.map_err(::failure::Error::from)
|
||||
.and_then(|mut file| {
|
||||
let mut buffer = vec![0; n];
|
||||
debug!("Allocated {} bytes", buffer.capacity());
|
||||
|
|
|
@ -43,11 +43,10 @@ extern crate toml_query;
|
|||
#[macro_use] extern crate libimagstore;
|
||||
extern crate libimagerror;
|
||||
#[macro_use] extern crate libimagentryutil;
|
||||
#[macro_use] extern crate error_chain;
|
||||
extern crate failure;
|
||||
|
||||
module_entry_path_mod!("ref");
|
||||
|
||||
pub mod error;
|
||||
pub mod reference;
|
||||
pub mod refstore;
|
||||
|
||||
|
|
|
@ -22,21 +22,20 @@
|
|||
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::result::Result as RResult;
|
||||
|
||||
use libimagentryutil::isa::Is;
|
||||
use libimagentryutil::isa::IsKindHeaderPathProvider;
|
||||
use libimagstore::store::Entry;
|
||||
use libimagerror::errors::ErrorMsg as EM;
|
||||
|
||||
use toml::Value;
|
||||
use toml_query::read::TomlValueReadExt;
|
||||
use toml_query::delete::TomlValueDeleteExt;
|
||||
use toml_query::insert::TomlValueInsertExt;
|
||||
use failure::Fallible as Result;
|
||||
use failure::Error;
|
||||
|
||||
use refstore::UniqueRefPathGenerator;
|
||||
use error::Result;
|
||||
use error::RefError as RE;
|
||||
use error::RefErrorKind as REK;
|
||||
|
||||
pub trait Ref {
|
||||
|
||||
|
@ -57,7 +56,7 @@ pub trait Ref {
|
|||
fn get_path(&self) -> Result<PathBuf>;
|
||||
|
||||
/// Check whether the referenced file still matches its hash
|
||||
fn hash_valid<RPG: UniqueRefPathGenerator>(&self) -> RResult<bool, RPG::Error>;
|
||||
fn hash_valid<RPG: UniqueRefPathGenerator>(&self) -> Result<bool>;
|
||||
|
||||
fn remove_ref(&mut self) -> Result<()>;
|
||||
|
||||
|
@ -84,15 +83,17 @@ impl Ref for Entry {
|
|||
|
||||
/// Check whether the underlying object is actually a ref
|
||||
fn is_ref(&self) -> Result<bool> {
|
||||
self.is::<IsRef>().map_err(From::from)
|
||||
self.is::<IsRef>().map_err(Error::from)
|
||||
}
|
||||
|
||||
fn get_hash(&self) -> Result<&str> {
|
||||
self.get_header()
|
||||
.read("ref.hash")
|
||||
.map_err(RE::from)?
|
||||
.ok_or_else(|| REK::HeaderFieldMissingError("ref.hash").into())
|
||||
.and_then(|v| v.as_str().ok_or_else(|| REK::HeaderTypeError("ref.hash", "string").into()))
|
||||
.map_err(Error::from)?
|
||||
.ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("ref.hash")))
|
||||
.and_then(|v| {
|
||||
v.as_str().ok_or_else(|| Error::from(EM::EntryHeaderTypeError2("ref.hash", "string")))
|
||||
})
|
||||
}
|
||||
|
||||
fn make_ref<P: AsRef<Path>>(&mut self, hash: String, path: P) -> Result<()> {
|
||||
|
@ -100,7 +101,7 @@ impl Ref for Entry {
|
|||
.as_ref()
|
||||
.to_str()
|
||||
.map(String::from)
|
||||
.ok_or_else(|| RE::from(REK::PathUTF8Error))?;
|
||||
.ok_or_else(|| EM::UTF8Error)?;
|
||||
|
||||
let _ = self.set_isflag::<IsRef>()?;
|
||||
let hdr = self.get_header_mut();
|
||||
|
@ -113,17 +114,20 @@ impl Ref for Entry {
|
|||
fn get_path(&self) -> Result<PathBuf> {
|
||||
self.get_header()
|
||||
.read("ref.path")
|
||||
.map_err(RE::from)?
|
||||
.ok_or_else(|| REK::HeaderFieldMissingError("ref.path").into())
|
||||
.and_then(|v| v.as_str().ok_or_else(|| REK::HeaderTypeError("ref.path", "string").into()))
|
||||
.map_err(Error::from)?
|
||||
.ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("ref.path")))
|
||||
.and_then(|v| {
|
||||
v.as_str()
|
||||
.ok_or_else(|| EM::EntryHeaderTypeError2("ref.path", "string"))
|
||||
.map_err(Error::from)
|
||||
})
|
||||
.map(PathBuf::from)
|
||||
}
|
||||
|
||||
fn hash_valid<RPG: UniqueRefPathGenerator>(&self) -> RResult<bool, RPG::Error> {
|
||||
fn hash_valid<RPG: UniqueRefPathGenerator>(&self) -> Result<bool> {
|
||||
self.get_path()
|
||||
.map(PathBuf::from)
|
||||
.map_err(RE::from)
|
||||
.map_err(RPG::Error::from)
|
||||
.map_err(Error::from)
|
||||
.and_then(|pb| RPG::unique_hash(pb))
|
||||
.and_then(|h| Ok(h == self.get_hash()?))
|
||||
}
|
||||
|
|
|
@ -24,26 +24,26 @@ use libimagstore::store::FileLockEntry;
|
|||
use libimagstore::store::Store;
|
||||
use libimagstore::storeid::StoreId;
|
||||
|
||||
use error::RefError as RE;
|
||||
use reference::Ref;
|
||||
|
||||
use failure::Fallible as Result;
|
||||
use failure::Error;
|
||||
|
||||
/// A UniqueRefPathGenerator generates unique Pathes
|
||||
///
|
||||
/// It is basically a functor which generates a StoreId from a &Path.
|
||||
/// For more information have a look at the documentation of RefStore.
|
||||
pub trait UniqueRefPathGenerator {
|
||||
type Error: From<RE>;
|
||||
|
||||
/// The collection the `StoreId` should be created for
|
||||
fn collection() -> &'static str {
|
||||
"ref"
|
||||
}
|
||||
|
||||
/// A function which should generate a unique string for a Path
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> Result<String, Self::Error>;
|
||||
fn unique_hash<A: AsRef<Path>>(path: A) -> Result<String>;
|
||||
|
||||
/// Postprocess the generated `StoreId` object
|
||||
fn postprocess_storeid(sid: StoreId) -> Result<StoreId, Self::Error> {
|
||||
fn postprocess_storeid(sid: StoreId) -> Result<StoreId> {
|
||||
Ok(sid)
|
||||
}
|
||||
}
|
||||
|
@ -80,45 +80,43 @@ pub trait UniqueRefPathGenerator {
|
|||
///
|
||||
pub trait RefStore<'a> {
|
||||
|
||||
fn get_ref<RPG: UniqueRefPathGenerator, H: AsRef<str>>(&'a self, hash: H) -> Result<Option<FileLockEntry<'a>>, RPG::Error>;
|
||||
fn create_ref<RPG: UniqueRefPathGenerator, A: AsRef<Path>>(&'a self, path: A) -> Result<FileLockEntry<'a>, RPG::Error>;
|
||||
fn retrieve_ref<RPG: UniqueRefPathGenerator, A: AsRef<Path>>(&'a self, path: A) -> Result<FileLockEntry<'a>, RPG::Error>;
|
||||
fn get_ref<RPG: UniqueRefPathGenerator, H: AsRef<str>>(&'a self, hash: H) -> Result<Option<FileLockEntry<'a>>>;
|
||||
fn create_ref<RPG: UniqueRefPathGenerator, A: AsRef<Path>>(&'a self, path: A) -> Result<FileLockEntry<'a>>;
|
||||
fn retrieve_ref<RPG: UniqueRefPathGenerator, A: AsRef<Path>>(&'a self, path: A) -> Result<FileLockEntry<'a>>;
|
||||
|
||||
}
|
||||
|
||||
impl<'a> RefStore<'a> for Store {
|
||||
|
||||
fn get_ref<RPG: UniqueRefPathGenerator, H: AsRef<str>>(&'a self, hash: H)
|
||||
-> Result<Option<FileLockEntry<'a>>, RPG::Error>
|
||||
-> Result<Option<FileLockEntry<'a>>>
|
||||
{
|
||||
let sid = StoreId::new_baseless(PathBuf::from(format!("{}/{}", RPG::collection(), hash.as_ref())))
|
||||
.map_err(RE::from)?;
|
||||
.map_err(Error::from)?;
|
||||
|
||||
debug!("Getting: {:?}", sid);
|
||||
self.get(sid)
|
||||
.map_err(RE::from)
|
||||
.map_err(RPG::Error::from)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
fn create_ref<RPG: UniqueRefPathGenerator, A: AsRef<Path>>(&'a self, path: A)
|
||||
-> Result<FileLockEntry<'a>, RPG::Error>
|
||||
-> Result<FileLockEntry<'a>>
|
||||
{
|
||||
let hash = RPG::unique_hash(&path)?;
|
||||
let pathbuf = PathBuf::from(format!("{}/{}", RPG::collection(), hash));
|
||||
let sid = StoreId::new_baseless(pathbuf.clone()).map_err(RE::from)?;
|
||||
let sid = StoreId::new_baseless(pathbuf.clone())?;
|
||||
|
||||
debug!("Creating: {:?}", sid);
|
||||
self.create(sid)
|
||||
.map_err(RE::from)
|
||||
.map_err(Error::from)
|
||||
.and_then(|mut fle| {
|
||||
fle.make_ref(hash, path)?;
|
||||
Ok(fle)
|
||||
})
|
||||
.map_err(RPG::Error::from)
|
||||
}
|
||||
|
||||
fn retrieve_ref<RPG: UniqueRefPathGenerator, A: AsRef<Path>>(&'a self, path: A)
|
||||
-> Result<FileLockEntry<'a>, RPG::Error>
|
||||
-> Result<FileLockEntry<'a>>
|
||||
{
|
||||
match self.get_ref::<RPG, String>(RPG::unique_hash(path.as_ref())?)? {
|
||||
Some(r) => Ok(r),
|
||||
|
|
Loading…
Reference in a new issue