From 1c851bbb797ec30b344fc3a86a5dd30d431ab9ed Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 16 Apr 2019 18:10:23 +0200 Subject: [PATCH] Rewrite store interface abstraction Because we pull in libimagentryref here to create actual references to the files we parse here, we need to rewrite the interface to be able to pass the required information to the libimagentryref API. Signed-off-by: Matthias Beyer --- lib/domain/libimagcontact/Cargo.toml | 3 +- lib/domain/libimagcontact/src/lib.rs | 1 + lib/domain/libimagcontact/src/store.rs | 98 +++++++++++++++++++++----- 3 files changed, 85 insertions(+), 17 deletions(-) diff --git a/lib/domain/libimagcontact/Cargo.toml b/lib/domain/libimagcontact/Cargo.toml index 36f2f989..b63b22fe 100644 --- a/lib/domain/libimagcontact/Cargo.toml +++ b/lib/domain/libimagcontact/Cargo.toml @@ -31,5 +31,6 @@ serde_derive = "1" libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" } -libimagentryutil = { version = "0.10.0", path = "../../../lib/entry/libimagentryutil/" } +libimagentryutil = { version = "0.10.0", path = "../../../lib/entry/libimagentryutil/" } +libimagentryref = { version = "0.10.0", path = "../../../lib/entry/libimagentryref/" } diff --git a/lib/domain/libimagcontact/src/lib.rs b/lib/domain/libimagcontact/src/lib.rs index 32eaffdd..0dc57e10 100644 --- a/lib/domain/libimagcontact/src/lib.rs +++ b/lib/domain/libimagcontact/src/lib.rs @@ -48,6 +48,7 @@ extern crate serde; #[macro_use] extern crate libimagstore; extern crate libimagerror; +extern crate libimagentryref; #[macro_use] extern crate libimagentryutil; module_entry_path_mod!("contact"); diff --git a/lib/domain/libimagcontact/src/store.rs b/lib/domain/libimagcontact/src/store.rs index 7c877832..3fd3771d 100644 --- a/lib/domain/libimagcontact/src/store.rs +++ b/lib/domain/libimagcontact/src/store.rs @@ -18,6 +18,7 @@ // use std::path::PathBuf; +use std::path::Path; use toml::Value; use toml::to_string as toml_to_string; @@ -32,6 +33,7 @@ use libimagstore::iter::Entries; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; use libimagentryutil::isa::Is; +use libimagentryref::reference::{MutRef, Config as RefConfig}; use contact::IsContact; use deser::DeserVcard; @@ -39,13 +41,23 @@ use util; pub trait ContactStore<'a> { - // creating + fn create_from_path(&'a self, p: &PathBuf, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef; - fn create_from_path(&'a self, p: &PathBuf) -> Result>; - fn retrieve_from_path(&'a self, p: &PathBuf) -> Result>; + fn retrieve_from_path(&'a self, p: &PathBuf, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef; - fn create_from_buf(&'a self, buf: &str) -> Result>; - fn retrieve_from_buf(&'a self, buf: &str) -> Result>; + fn create_from_buf(&'a self, buf: &str, path: P, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef, + P: AsRef; + + fn retrieve_from_buf(&'a self, buf: &str, path: P, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef, + P: AsRef; // getting @@ -55,23 +67,58 @@ pub trait ContactStore<'a> { /// The extension for the Store to work with contacts impl<'a> ContactStore<'a> for Store { - fn create_from_path(&'a self, p: &PathBuf) -> Result> { - util::read_to_string(p).and_then(|buf| self.create_from_buf(&buf)) + /// Create a contact from a filepath + /// + /// Uses the collection with `collection_name` from RefConfig to store the reference to the + /// file. + fn create_from_path(&'a self, p: &PathBuf, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef + { + util::read_to_string(p).and_then(|buf| self.create_from_buf(&buf, p, rc, collection_name)) } - fn retrieve_from_path(&'a self, p: &PathBuf) -> Result> { - util::read_to_string(p).and_then(|buf| self.retrieve_from_buf(&buf)) + /// Retrieve a contact from a filepath + /// + /// Uses the collection with `collection_name` from RefConfig to store the reference to the + /// file. + fn retrieve_from_path(&'a self, p: &PathBuf, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef + { + util::read_to_string(p).and_then(|buf| self.retrieve_from_buf(&buf, p, rc, collection_name)) } - /// Create contact ref from buffer - fn create_from_buf(&'a self, buf: &str) -> Result> { + /// Create a contact from a buffer + /// + /// Uses the collection with `collection_name` from RefConfig to store the reference to the + /// file. + /// + /// Needs the `path` passed where the buffer was read from, because we want to create a + /// reference to it. + fn create_from_buf(&'a self, buf: &str, path: P, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef, + P: AsRef + { let (sid, value) = prepare_fetching_from_store(buf)?; - postprocess_fetched_entry(self.create(sid)?, value) + postprocess_fetched_entry(self.create(sid)?, value, path, rc, collection_name) } - fn retrieve_from_buf(&'a self, buf: &str) -> Result> { + /// Retrieve a contact from a buffer + /// + /// Uses the collection with `collection_name` from RefConfig to store the reference to the + /// file. + /// + /// Needs the `path` passed where the buffer was read from, because we want to create a + /// reference to it. + fn retrieve_from_buf(&'a self, buf: &str, path: P, rc: &RefConfig, collection_name: CN) + -> Result> + where CN: AsRef, + P: AsRef + { let (sid, value) = prepare_fetching_from_store(buf)?; - postprocess_fetched_entry(self.retrieve(sid)?, value) + postprocess_fetched_entry(self.retrieve(sid)?, value, path, rc, collection_name) } fn all_contacts(&'a self) -> Result> { @@ -101,10 +148,29 @@ fn prepare_fetching_from_store(buf: &str) -> Result<(StoreId, Value)> { Ok((sid, value)) } -/// Postprocess the entry just fetched from the store -fn postprocess_fetched_entry<'a>(mut entry: FileLockEntry<'a>, value: Value) -> Result> { +/// Postprocess the entry just fetched (created or retrieved) from the store +/// +/// We need the path, the refconfig and the collection name passed here because we create a +/// reference here. +/// +/// This is marked as inline because what it does is trivial, but repetitve in this module. +#[inline] +fn postprocess_fetched_entry<'a, CN, P>(mut entry: FileLockEntry<'a>, + value: Value, + path: P, + rc: &RefConfig, + collection_name: CN) + -> Result> + where CN: AsRef, + P: AsRef +{ + use libimagentryref::reference::RefFassade; + use libimagentryref::hasher::sha1::Sha1Hasher; + entry.set_isflag::()?; entry.get_header_mut().insert("contact.data", value)?; + entry.as_ref_with_hasher_mut::().make_ref(path, collection_name, rc, false)?; + Ok(entry) }