summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-02-14 14:09:59 +0100
committerMatthias Beyer <mail@beyermatthias.de>2018-02-19 12:14:32 +0100
commita1a85f40d0e1bccb1874fc300c8f3f7558aff677 (patch)
treedf4f7fa2fc4bdfc921aff3794d530ad7d01036f3
parent2328c8b2b01c60395aafce04cdd60596656c2696 (diff)
Add default generators
-rw-r--r--lib/entry/libimagentryref/Cargo.toml15
-rw-r--r--lib/entry/libimagentryref/src/generators/base.rs48
-rw-r--r--lib/entry/libimagentryref/src/generators/mod.rs259
-rw-r--r--lib/entry/libimagentryref/src/lib.rs13
4 files changed, 335 insertions, 0 deletions
diff --git a/lib/entry/libimagentryref/Cargo.toml b/lib/entry/libimagentryref/Cargo.toml
index 5e1f7f9a..46178af7 100644
--- a/lib/entry/libimagentryref/Cargo.toml
+++ b/lib/entry/libimagentryref/Cargo.toml
@@ -30,3 +30,18 @@ libimagstore = { version = "0.7.0", path = "../../../lib/core/libimagstore"
libimagerror = { version = "0.7.0", path = "../../../lib/core/libimagerror" }
libimagentrylist = { version = "0.7.0", path = "../../../lib/entry/libimagentrylist" }
libimagentryutil = { version = "0.7.0", path = "../../../lib/entry/libimagentryutil" }
+
+[dependencies.rust-crypto]
+version = "0.2"
+optional = true
+
+[features]
+default = []
+generators = []
+generators-sha1 = ["rust-crypto"]
+generators-sha224 = ["rust-crypto"]
+generators-sha256 = ["rust-crypto"]
+generators-sha384 = ["rust-crypto"]
+generators-sha512 = ["rust-crypto"]
+generators-sha3 = ["rust-crypto"]
+
diff --git a/lib/entry/libimagentryref/src/generators/base.rs b/lib/entry/libimagentryref/src/generators/base.rs
new file mode 100644
index 00000000..aea60b28
--- /dev/null
+++ b/lib/entry/libimagentryref/src/generators/base.rs
@@ -0,0 +1,48 @@
+//
+// 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
+//
+
+use std::path::Path;
+
+use libimagstore::storeid::StoreId;
+
+use error::RefError;
+use refstore::UniqueRefPathGenerator;
+
+/// 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> {
+ // This has to be overridden
+ panic!("Not overridden base functionality. This is a BUG!")
+ }
+
+ fn postprocess_storeid(sid: StoreId) -> Result<StoreId, Self::Error> {
+ Ok(sid) // default implementation
+ }
+}
+
diff --git a/lib/entry/libimagentryref/src/generators/mod.rs b/lib/entry/libimagentryref/src/generators/mod.rs
new file mode 100644
index 00000000..730fd640
--- /dev/null
+++ b/lib/entry/libimagentryref/src/generators/mod.rs
@@ -0,0 +1,259 @@
+//
+// 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
+//
+
+//! Default generators
+//!
+//! This module provides a number of default `UniqueRefPathGenerator`s
+//! which can be used for generating references.
+//!
+//! These generators are _NOT_ domain specific. So there won't be a "UniqueMailRefPathGenerator" in
+//! here, for example.
+//!
+//! All these generators use "ref" as collection name.
+//! They can be overridden using the `make_unique_ref_path_generator!()` convenience macro.
+//!
+//! # Note
+//!
+//! You must enable the appropriate crate feature to use any of the provided generators. With the
+//! `generators` feature, you only get the convenience macro `make_unique_ref_path_generator!()`.
+//!
+
+/// A convenience macro for wrapping a generator in a new one, reusing the functionality from the
+/// underlying generator
+///
+/// The UniqueRefPathGenerator must be in scope.
+///
+/// The macro creates a new struct `$name` over `$underlying` and changes the collection name to
+/// `$collectionname`.
+/// If passed, the new implementation is used (defaults to the implementation from the underlying
+/// generator).
+/// If passed, the new postprocessing is used (defaults to not changing the StoreId)
+///
+#[macro_export]
+macro_rules! make_unique_ref_path_generator {
+ (
+ $name:ident
+ over $underlying:ty
+ => with error $errtype:ty
+ => with collection name $collectionname:expr
+ ) => {
+ struct $name;
+ impl_unique_ref_path_generator_trait!(
+ $name
+ over $underlying
+ => with error $errtype
+ => with collection name $collectionname
+ => |p| { $underlying::unique_hash(p) } => |s| { Ok(s) }
+ );
+ };
+
+ (
+ $name:ident
+ over $underlying:ty
+ => with error $errtype:ty
+ => with collection name $collectionname:expr
+ => $impl:expr
+ ) => {
+ struct $name;
+ impl_unique_ref_path_generator_trait!(
+ $name
+ over $underlying
+ => with error $errtype
+ => with collection name $collectionname
+ => $impl => |sid| { Ok(sid) }
+ );
+ };
+
+ (
+ 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) }
+ );
+ };
+
+ (
+ pub $name:ident
+ over $underlying:ty
+ => with error $errtype:ty
+ => with collection name $collectionname:expr
+ => $impl:expr
+ => $postproc:expr
+ ) => {
+ pub struct $name;
+ impl_unique_ref_path_generator_trait!(
+ $name, $underlying, $errtype, $collectionname => $impl => $postproc
+ );
+ };
+}
+
+macro_rules! impl_unique_ref_path_generator_trait {
+ ($name:ident, $underlying:ty, $errtype:ty, $collectionname:expr => $impl:expr => $postproc:expr) => {
+ 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> {
+ $impl(path)
+ }
+
+ fn postprocess_storeid(sid: ::libimagstore::storeid::StoreId)
+ -> Result<::libimagstore::storeid::StoreId, Self::Error>
+ {
+ $postproc(sid)
+ }
+ }
+ }
+}
+
+
+#[cfg(any(
+ feature = "generators-sha1",
+ feature = "generators-sha224",
+ feature = "generators-sha256",
+ feature = "generators-sha384",
+ feature = "generators-sha512",
+ feature = "generators-sha3",
+ ))]
+mod base;
+
+/// Helper macro for generating implementations for the various Sha algorithms
+macro_rules! make_sha_mod {
+ {
+ $modname:ident,
+ $hashname:ident,
+ $hashingimpl:expr
+ } => {
+ pub mod $modname {
+ use std::path::Path;
+ use std::fs::OpenOptions;
+ use std::io::Read;
+
+ use error::RefError as RE;
+
+ use crypto::digest::Digest;
+ make_unique_ref_path_generator! (
+ pub $hashname
+ over generators::base::Base
+ => with error RE
+ => with collection name "ref"
+ => |path| {
+ OpenOptions::new()
+ .read(true)
+ .write(false)
+ .create(false)
+ .open(path)
+ .map_err(RE::from)
+ .and_then(|mut file| {
+ let mut buffer = String::new();
+ let _ = file.read_to_string(&mut buffer)?;
+ $hashingimpl(buffer)
+ })
+ }
+ );
+
+ 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> {
+ OpenOptions::new()
+ .read(true)
+ .write(false)
+ .create(false)
+ .open(path)
+ .map_err(RE::from)
+ .and_then(|mut file| {
+ let mut buffer = Vec::with_capacity(n);
+ let _ = file.read_exact(&mut buffer)?;
+ let buffer = String::from_utf8(buffer)?;
+ $hashingimpl(buffer)
+ })
+ }
+
+ }
+
+ }
+ }
+}
+
+#[cfg(feature = "generators-sha1")]
+make_sha_mod! {
+ sha1, Sha1, |buffer: String| {
+ let mut hasher = ::crypto::sha1::Sha1::new();
+ hasher.input_str(&buffer);
+ Ok(String::from(hasher.result_str()))
+ }
+}
+
+#[cfg(feature = "generators-sha224")]
+make_sha_mod! {
+ sha224, Sha224, |buffer: String| {
+ let mut hasher = ::crypto::sha2::Sha224::new();
+ hasher.input_str(&buffer);
+ Ok(String::from(hasher.result_str()))
+ }
+}
+
+#[cfg(feature = "generators-sha256")]
+make_sha_mod! {
+ sha256, Sha256, |buffer: String| {
+ let mut hasher = ::crypto::sha2::Sha256::new();
+ hasher.input_str(&buffer);
+ Ok(String::from(hasher.result_str()))
+ }
+}
+
+#[cfg(feature = "generators-sha384")]
+make_sha_mod! {
+ sha384, Sha384, |buffer: String| {
+ let mut hasher = ::crypto::sha2::Sha384::new();
+ hasher.input_str(&buffer);
+ Ok(String::from(hasher.result_str()))
+ }
+}
+
+#[cfg(feature = "generators-sha512")]
+make_sha_mod! {
+ sha512, Sha512, |buffer: String| {
+ let mut hasher = ::crypto::sha2::Sha512::new();
+ hasher.input_str(&buffer);
+ Ok(String::from(hasher.result_str()))
+ }
+}
+
+#[cfg(feature = "generators-sha3")]
+make_sha_mod! {
+ sha3, Sha3, |buffer: String| {
+ let mut hasher = ::crypto::sha3::Sha3::sha3_256();
+ hasher.input_str(&buffer);
+ Ok(String::from(hasher.result_str()))
+ }
+}
+
diff --git a/lib/entry/libimagentryref/src/lib.rs b/lib/entry/libimagentryref/src/lib.rs
index 7311d13b..39f3c546 100644
--- a/lib/entry/libimagentryref/src/lib.rs
+++ b/lib/entry/libimagentryref/src/lib.rs
@@ -52,3 +52,16 @@ pub mod error;
pub mod reference;
pub mod refstore;
+#[cfg(any(
+ feature = "generators-sha1",
+ feature = "generators-sha224",
+ feature = "generators-sha256",
+ feature = "generators-sha384",
+ feature = "generators-sha512",
+ feature = "generators-sha3",
+))]
+extern crate crypto;
+
+#[cfg(feature = "generators")]
+pub mod generators;
+