From 434505f1f086da7ed72b808d25da0bf894f58477 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 17:23:40 +0200 Subject: [PATCH 01/13] Initial import of libimagcontact --- Cargo.toml | 1 + lib/domain/libimagcontact/Cargo.toml | 26 +++++++++++++++ lib/domain/libimagcontact/src/lib.rs | 47 ++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 lib/domain/libimagcontact/Cargo.toml create mode 100644 lib/domain/libimagcontact/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index e9276006..21f3a85e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ members = [ "lib/core/libimagrt", "lib/core/libimagstore", "lib/domain/libimagbookmark", + "lib/domain/libimagcontact", "lib/domain/libimagdiary", "lib/domain/libimagmail", "lib/domain/libimagnotes", diff --git a/lib/domain/libimagcontact/Cargo.toml b/lib/domain/libimagcontact/Cargo.toml new file mode 100644 index 00000000..acc420aa --- /dev/null +++ b/lib/domain/libimagcontact/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "libimagcontact" +version = "0.5.0" +authors = ["Matthias Beyer "] + +description = "Library for the imag core distribution" + +keywords = ["imag", "PIM", "personal", "information", "management"] +readme = "../../../README.md" +license = "LGPL-2.1" + +documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.html" +repository = "https://github.com/matthiasbeyer/imag" +homepage = "http://imag-pim.org" + +[dependencies] +error-chain = "0.11" +log = "0.3" +toml = "0.4" +toml-query = "0.4" +vobject = { git = 'https://github.com/matthiasbeyer/rust-vobject', branch = "next" } + +libimagstore = { version = "0.5.0", path = "../../../lib/core/libimagstore" } +libimagerror = { version = "0.5.0", path = "../../../lib/core/libimagerror" } +libimagentryref = { version = "0.5.0", path = "../../../lib/entry/libimagentryref/" } + diff --git a/lib/domain/libimagcontact/src/lib.rs b/lib/domain/libimagcontact/src/lib.rs new file mode 100644 index 00000000..566a7df5 --- /dev/null +++ b/lib/domain/libimagcontact/src/lib.rs @@ -0,0 +1,47 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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 +// + +#![deny( + dead_code, + non_camel_case_types, + non_snake_case, + path_statements, + trivial_numeric_casts, + unstable_features, + unused_allocation, + unused_import_braces, + unused_imports, + unused_must_use, + unused_mut, + unused_qualifications, + while_true, +)] + +#[macro_use] extern crate log; +#[macro_use] extern crate error_chain; +extern crate vobject; +extern crate toml; +extern crate toml_query; + +#[macro_use] extern crate libimagstore; +extern crate libimagerror; +extern crate libimagentryref; + +module_entry_path_mod!("contact"); + From eaa9ad5993b50fc28e6c79639c47d301a0610b65 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 17:50:23 +0200 Subject: [PATCH 02/13] Add basic documentation on how the lib works --- doc/src/05100-lib-contacts.md | 47 +++++++++++++++++++++++++++++ lib/domain/libimagcontact/README.md | 1 + 2 files changed, 48 insertions(+) create mode 120000 lib/domain/libimagcontact/README.md diff --git a/doc/src/05100-lib-contacts.md b/doc/src/05100-lib-contacts.md index 4bdd5371..25e69069 100644 --- a/doc/src/05100-lib-contacts.md +++ b/doc/src/05100-lib-contacts.md @@ -1,2 +1,49 @@ ## libimagcontacts +The contact library basically only creates references to the actual icalendar +and vcard files, though it also can parse (via the `vobject` crate) the +information and return it from an entry directly. + +The architecture of indirections is as follows: + +```{.numberLines} + ++--------------------------------+ +| | +| Store, as ContactStore | +| | ++----------------+---------------+ + | + | Provides access to + | ++----------------v---------------+ +| | +| (FileLock)Entry as Contact | +| | +| which is actually a: | +| | +| (FileLock)Entry as Ref | +| | ++----------------+---------------+ + | + | refers to + | ++----------------v---------------+ +| | +| vcard file (outside store) | +| | ++----------------+---------------+ + | + | contains + | ++----------------v---------------+ +| | +| vcard data | +| | ++--------------------------------+ + +``` + +As the library is build upon `libimagentryref`, it does not create a new +subcollection in the store `/contacts`, but uses the infrastructure of +`libimagentryref` which automatically puts all references in `/ref`. diff --git a/lib/domain/libimagcontact/README.md b/lib/domain/libimagcontact/README.md new file mode 120000 index 00000000..e097eece --- /dev/null +++ b/lib/domain/libimagcontact/README.md @@ -0,0 +1 @@ +../../../doc/src/05100-lib-contacts.md \ No newline at end of file From 04182f5cb665a41264d3421a66b07719fb696381 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 17:51:35 +0200 Subject: [PATCH 03/13] Add initial layout of code --- lib/domain/libimagcontact/src/contact.rs | 49 ++++++++++++++++++++++++ lib/domain/libimagcontact/src/error.rs | 38 ++++++++++++++++++ lib/domain/libimagcontact/src/lib.rs | 4 ++ lib/domain/libimagcontact/src/store.rs | 48 +++++++++++++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 lib/domain/libimagcontact/src/contact.rs create mode 100644 lib/domain/libimagcontact/src/error.rs create mode 100644 lib/domain/libimagcontact/src/store.rs diff --git a/lib/domain/libimagcontact/src/contact.rs b/lib/domain/libimagcontact/src/contact.rs new file mode 100644 index 00000000..d2cc3059 --- /dev/null +++ b/lib/domain/libimagcontact/src/contact.rs @@ -0,0 +1,49 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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 vobject::Component; + +use libimagstore::store::Entry; +use libimagentryref::reference::Ref; + +use error::Result; + +/// Trait to be implemented on ::libimagstore::store::Entry +/// +/// Based on the functionality from libimagentryref, for fetching the Ical data from disk +pub trait Contact : Ref { + + // getting data + + fn get_contact_data(&self) -> Result; + + // More convenience functionality may follow + +} + +impl Contact for Entry { + fn get_contact_data(&self) -> Result { + unimplemented!() + } +} + +pub struct ContactData { + components: Vec, +} + diff --git a/lib/domain/libimagcontact/src/error.rs b/lib/domain/libimagcontact/src/error.rs new file mode 100644 index 00000000..eea164e4 --- /dev/null +++ b/lib/domain/libimagcontact/src/error.rs @@ -0,0 +1,38 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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 { + ContactError, ContactErrorKind, ResultExt, Result; + } + + links { + StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); + } + + foreign_links { + Io(::std::io::Error); + TomlQueryError(::toml_query::error::Error); + } + + errors { + + } +} + diff --git a/lib/domain/libimagcontact/src/lib.rs b/lib/domain/libimagcontact/src/lib.rs index 566a7df5..56cad7f7 100644 --- a/lib/domain/libimagcontact/src/lib.rs +++ b/lib/domain/libimagcontact/src/lib.rs @@ -45,3 +45,7 @@ extern crate libimagentryref; module_entry_path_mod!("contact"); +pub mod contact; +pub mod error; +pub mod store; + diff --git a/lib/domain/libimagcontact/src/store.rs b/lib/domain/libimagcontact/src/store.rs new file mode 100644 index 00000000..4b780525 --- /dev/null +++ b/lib/domain/libimagcontact/src/store.rs @@ -0,0 +1,48 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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::PathBuf; + +use libimagstore::store::Store; +use libimagstore::store::FileLockEntry; + +use error::Result; + +pub trait ContactStore<'a> { + + // creating + + fn create_from_path(&'a self, p: &PathBuf) -> Result>; + + // getting + + fn search_contact(&'a self /* later more params */) -> Result>; +} + +impl<'a> ContactStore<'a> for Store { + + fn create_from_path(&'a self, p: &PathBuf) -> Result> { + unimplemented!() + } + + fn search_contact(&'a self /* later more params */) -> Result> { + unimplemented!() + } + +} From 577f8d313a5565f516d44c8e2a10fa8c7601c83e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 20:17:42 +0200 Subject: [PATCH 04/13] Add more error links --- lib/domain/libimagcontact/src/error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/domain/libimagcontact/src/error.rs b/lib/domain/libimagcontact/src/error.rs index eea164e4..f9676357 100644 --- a/lib/domain/libimagcontact/src/error.rs +++ b/lib/domain/libimagcontact/src/error.rs @@ -24,11 +24,13 @@ error_chain! { links { StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); + RefError(::libimagentryref::error::RefError, ::libimagentryref::error::RefErrorKind); } foreign_links { Io(::std::io::Error); TomlQueryError(::toml_query::error::Error); + VObjectError(::vobject::ParseError); } errors { From c14c19483cf8e1ad64c26440cdb759e9ab2c01dd Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 20:18:03 +0200 Subject: [PATCH 05/13] Add lib internal utilities --- lib/domain/libimagcontact/src/lib.rs | 1 + lib/domain/libimagcontact/src/util.rs | 45 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 lib/domain/libimagcontact/src/util.rs diff --git a/lib/domain/libimagcontact/src/lib.rs b/lib/domain/libimagcontact/src/lib.rs index 56cad7f7..73f36283 100644 --- a/lib/domain/libimagcontact/src/lib.rs +++ b/lib/domain/libimagcontact/src/lib.rs @@ -48,4 +48,5 @@ module_entry_path_mod!("contact"); pub mod contact; pub mod error; pub mod store; +mod util; diff --git a/lib/domain/libimagcontact/src/util.rs b/lib/domain/libimagcontact/src/util.rs new file mode 100644 index 00000000..0dad5978 --- /dev/null +++ b/lib/domain/libimagcontact/src/util.rs @@ -0,0 +1,45 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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 std::fmt::Debug; +use std::fs::File; +use std::io::Read; + +use error::Result; + +use vobject::Component; + +pub fn read_to_string + Debug>(pb: A) -> Result { + let mut cont = String::new(); + + let mut file = File::open(pb.as_ref())?; + let bytes = file.read_to_string(&mut cont)?; + + debug!("Read {} bytes from {:?}", bytes, pb); + + Ok(cont) +} + +/// Helper for chaining results nicely +pub fn parse(buf: String) -> Result { + use vobject::parse_component; + parse_component(&buf).map_err(From::from) +} + From ce5e7f5252ae23e7b0dab73dcc33ae0c99a2cb77 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 20:18:20 +0200 Subject: [PATCH 06/13] Impl Store::create_from_path() --- lib/domain/libimagcontact/src/store.rs | 33 ++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/domain/libimagcontact/src/store.rs b/lib/domain/libimagcontact/src/store.rs index 4b780525..4d166bf6 100644 --- a/lib/domain/libimagcontact/src/store.rs +++ b/lib/domain/libimagcontact/src/store.rs @@ -19,17 +19,30 @@ use std::path::PathBuf; +use vobject::parse_component; +use toml::Value; +use toml_query::insert::TomlValueInsertExt; + use libimagstore::store::Store; use libimagstore::store::FileLockEntry; +use libimagentryref::refstore::RefStore; +use libimagentryref::flags::RefFlags; use error::Result; +use util; -pub trait ContactStore<'a> { +pub trait ContactStore<'a> : RefStore { // creating fn create_from_path(&'a self, p: &PathBuf) -> Result>; + /// Create contact ref from buffer + /// + /// Needs the `p` argument as we're finally creating a reference by path, the buffer is only for + /// collecting metadata. + fn create_from_buf(&'a self, p: &PathBuf, buf: &String) -> Result>; + // getting fn search_contact(&'a self /* later more params */) -> Result>; @@ -38,7 +51,23 @@ pub trait ContactStore<'a> { impl<'a> ContactStore<'a> for Store { fn create_from_path(&'a self, p: &PathBuf) -> Result> { - unimplemented!() + util::read_to_string(p).and_then(|buf| self.create_from_buf(p, &buf)) + } + + /// Create contact ref from buffer + fn create_from_buf(&'a self, p: &PathBuf, buf: &String) -> Result> { + let component = parse_component(&buf)?; + debug!("Parsed: {:?}", component); + + let flags = RefFlags::default().with_content_hashing(true).with_permission_tracking(false); + RefStore::create(self, p.clone(), flags) + .map_err(From::from) + .and_then(|mut entry| { + entry.get_header_mut() + .insert("contact.marker", Value::Boolean(true)) + .map_err(From::from) + .map(|_| entry) + }) } fn search_contact(&'a self /* later more params */) -> Result> { From aae19221b6450ef86c69572787b7b19d6cad0f65 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 20:18:30 +0200 Subject: [PATCH 07/13] Impl Contact::get_contact_data() --- lib/domain/libimagcontact/src/contact.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/domain/libimagcontact/src/contact.rs b/lib/domain/libimagcontact/src/contact.rs index d2cc3059..61dea3ab 100644 --- a/lib/domain/libimagcontact/src/contact.rs +++ b/lib/domain/libimagcontact/src/contact.rs @@ -23,6 +23,7 @@ use libimagstore::store::Entry; use libimagentryref::reference::Ref; use error::Result; +use util; /// Trait to be implemented on ::libimagstore::store::Entry /// @@ -38,12 +39,19 @@ pub trait Contact : Ref { } impl Contact for Entry { + fn get_contact_data(&self) -> Result { - unimplemented!() + let component = self + .fs_file() + .map_err(From::from) + .and_then(util::read_to_string) + .and_then(util::parse)?; + + Ok(ContactData(component)) } + } -pub struct ContactData { - components: Vec, -} +pub struct ContactData(Component); + From f2bd241a59e1d93b47c725965e5b67d99277c93d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 20:24:54 +0200 Subject: [PATCH 08/13] Add error for header type error --- lib/domain/libimagcontact/src/error.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/domain/libimagcontact/src/error.rs b/lib/domain/libimagcontact/src/error.rs index f9676357..f433684d 100644 --- a/lib/domain/libimagcontact/src/error.rs +++ b/lib/domain/libimagcontact/src/error.rs @@ -35,6 +35,11 @@ error_chain! { errors { + HeaderTypeError(ty: &'static str, loc: &'static str) { + description("Type error in header") + display("Type error in header, expected {} at '{}', found other type", ty, loc) + } + } } From 12e8657eb9505488a27a44800bf460c0c9139bed Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Sep 2017 20:25:10 +0200 Subject: [PATCH 09/13] Add Contact::is_contact() --- lib/domain/libimagcontact/src/contact.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/domain/libimagcontact/src/contact.rs b/lib/domain/libimagcontact/src/contact.rs index 61dea3ab..37735f88 100644 --- a/lib/domain/libimagcontact/src/contact.rs +++ b/lib/domain/libimagcontact/src/contact.rs @@ -18,10 +18,14 @@ // use vobject::Component; +use toml::Value; +use toml_query::read::TomlValueReadExt; use libimagstore::store::Entry; use libimagentryref::reference::Ref; +use error::ContactError as CE; +use error::ContactErrorKind as CEK; use error::Result; use util; @@ -30,6 +34,8 @@ use util; /// Based on the functionality from libimagentryref, for fetching the Ical data from disk pub trait Contact : Ref { + fn is_contact(&self) -> Result; + // getting data fn get_contact_data(&self) -> Result; @@ -40,6 +46,15 @@ pub trait Contact : Ref { impl Contact for Entry { + fn is_contact(&self) -> Result { + let location = "contact.marker"; + match self.get_header().read(location)? { + Some(&Value::Boolean(b)) => Ok(b), + Some(_) => Err(CE::from_kind(CEK::HeaderTypeError("boolean", location))), + None => Ok(false) + } + } + fn get_contact_data(&self) -> Result { let component = self .fs_file() From f3d75e97b6b61748a55ea4fe90f372ec8a1d4a77 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 30 Sep 2017 19:46:04 +0200 Subject: [PATCH 10/13] Rely on own clone of rust-vobject --- lib/domain/libimagcontact/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/domain/libimagcontact/src/error.rs b/lib/domain/libimagcontact/src/error.rs index f433684d..88ffa803 100644 --- a/lib/domain/libimagcontact/src/error.rs +++ b/lib/domain/libimagcontact/src/error.rs @@ -25,12 +25,12 @@ error_chain! { links { StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); RefError(::libimagentryref::error::RefError, ::libimagentryref::error::RefErrorKind); + VObjectError(::vobject::error::VObjectError, ::vobject::error::VObjectErrorKind); } foreign_links { Io(::std::io::Error); TomlQueryError(::toml_query::error::Error); - VObjectError(::vobject::ParseError); } errors { From b05c8c6f6dc57bf1a121cb9684420ef08fceff61 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 2 Oct 2017 20:44:08 +0200 Subject: [PATCH 11/13] Replace search_contact() with all_contacts() We can then use filters to filter out the non relevant ones. --- lib/domain/libimagcontact/src/store.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/domain/libimagcontact/src/store.rs b/lib/domain/libimagcontact/src/store.rs index 4d166bf6..770c08ff 100644 --- a/lib/domain/libimagcontact/src/store.rs +++ b/lib/domain/libimagcontact/src/store.rs @@ -25,6 +25,7 @@ use toml_query::insert::TomlValueInsertExt; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; +use libimagstore::storeid::StoreIdIterator; use libimagentryref::refstore::RefStore; use libimagentryref::flags::RefFlags; @@ -45,9 +46,16 @@ pub trait ContactStore<'a> : RefStore { // getting - fn search_contact(&'a self /* later more params */) -> Result>; + fn all_contacts(&'a self) -> Result; } +/// The extension for the Store to work with contacts +/// +/// The contact functionality is implemented by using the `libimagentryref` library, so basically +/// we only reference vcard files from outside the store. +/// +/// Because of this, we do not have an own store collection `/contacts` or something like that, but +/// must stress the `libimagentryref` API for everything. impl<'a> ContactStore<'a> for Store { fn create_from_path(&'a self, p: &PathBuf) -> Result> { @@ -70,8 +78,9 @@ impl<'a> ContactStore<'a> for Store { }) } - fn search_contact(&'a self /* later more params */) -> Result> { - unimplemented!() + fn all_contacts(&'a self) -> Result { + self.all_references().map_err(From::from) } } + From 4fa41faa590601e4abcb5ee283f7cb9f9e07fe56 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 2 Oct 2017 20:55:42 +0200 Subject: [PATCH 12/13] Add iterator for contacts --- lib/domain/libimagcontact/src/error.rs | 7 +++ lib/domain/libimagcontact/src/iter.rs | 69 ++++++++++++++++++++++++++ lib/domain/libimagcontact/src/lib.rs | 1 + 3 files changed, 77 insertions(+) create mode 100644 lib/domain/libimagcontact/src/iter.rs diff --git a/lib/domain/libimagcontact/src/error.rs b/lib/domain/libimagcontact/src/error.rs index 88ffa803..c3c81472 100644 --- a/lib/domain/libimagcontact/src/error.rs +++ b/lib/domain/libimagcontact/src/error.rs @@ -17,6 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // +use libimagstore::storeid::StoreId; + error_chain! { types { ContactError, ContactErrorKind, ResultExt, Result; @@ -40,6 +42,11 @@ error_chain! { display("Type error in header, expected {} at '{}', found other type", ty, loc) } + EntryNotFound(sid: StoreId) { + description("Entry not found with StoreId") + display("Entry {:?} not found", sid) + } + } } diff --git a/lib/domain/libimagcontact/src/iter.rs b/lib/domain/libimagcontact/src/iter.rs new file mode 100644 index 00000000..b5f8974a --- /dev/null +++ b/lib/domain/libimagcontact/src/iter.rs @@ -0,0 +1,69 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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 libimagstore::storeid::StoreIdIterator; +use libimagstore::store::Store; +use libimagstore::store::FileLockEntry; + +use contact::Contact; +use error::ContactError as CE; +use error::ContactErrorKind as CEK; +use error::Result; + +pub struct ContactIter<'a>(StoreIdIterator, &'a Store); + +/// Iterator over contacts +/// +/// As the libimagcontact works with libimagentryref in the backend, we must hold a reference to the +/// Store here as well, so we can check whether a fetched StoreId actually points to a contact +/// reference or not. +/// +/// So, the Iterator `Store::get()`s the object pointed to by the StoreId and returns it if +/// everything worked. +impl<'a> ContactIter<'a> { + + pub fn new(sii: StoreIdIterator, store: &'a Store) -> ContactIter<'a> { + ContactIter(sii, store) + } + +} + +impl<'a> Iterator for ContactIter<'a> { + type Item = Result>; + + fn next(&mut self) -> Option { + loop { + match self.0.next() { + None => return None, + Some(sid) => match self.1.get(sid.clone()).map_err(From::from) { + Err(e) => return Some(Err(e)), + Ok(None) => return Some(Err(CE::from_kind(CEK::EntryNotFound(sid)))), + Ok(Some(entry)) => match entry.is_contact().map_err(From::from) { + Ok(true) => return Some(Ok(entry)), + Ok(false) => continue, + Err(e) => return Some(Err(e)), + }, + + }, + } + } + } + +} + diff --git a/lib/domain/libimagcontact/src/lib.rs b/lib/domain/libimagcontact/src/lib.rs index 73f36283..efdb8a60 100644 --- a/lib/domain/libimagcontact/src/lib.rs +++ b/lib/domain/libimagcontact/src/lib.rs @@ -47,6 +47,7 @@ module_entry_path_mod!("contact"); pub mod contact; pub mod error; +pub mod iter; pub mod store; mod util; From dfbc69400a578edcb77e248c821d949e2bc68217 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 10 Oct 2017 18:47:54 +0200 Subject: [PATCH 13/13] Let ContactData be unpacked and derefd --- lib/domain/libimagcontact/src/contact.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/domain/libimagcontact/src/contact.rs b/lib/domain/libimagcontact/src/contact.rs index 37735f88..14a80e3b 100644 --- a/lib/domain/libimagcontact/src/contact.rs +++ b/lib/domain/libimagcontact/src/contact.rs @@ -17,6 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // +use std::ops::Deref; + use vobject::Component; use toml::Value; use toml_query::read::TomlValueReadExt; @@ -69,4 +71,20 @@ impl Contact for Entry { pub struct ContactData(Component); +impl ContactData { + + pub fn into_inner(self) -> Component { + self.0 + } + +} + +impl Deref for ContactData { + type Target = Component; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +