From c05c8840306c673b9e66a388daef039cc56b3f16 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 14:53:57 +0200 Subject: [PATCH 01/22] Initial codebase --- libimagannotation/Cargo.toml | 6 ++++++ libimagannotation/src/lib.rs | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 libimagannotation/Cargo.toml create mode 100644 libimagannotation/src/lib.rs diff --git a/libimagannotation/Cargo.toml b/libimagannotation/Cargo.toml new file mode 100644 index 00000000..d4268e9e --- /dev/null +++ b/libimagannotation/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "libimagannotation" +version = "0.1.0" +authors = ["Matthias Beyer "] + +[dependencies] diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs new file mode 100644 index 00000000..cdfbe1aa --- /dev/null +++ b/libimagannotation/src/lib.rs @@ -0,0 +1,6 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + } +} From 4a36d4efc935e17c350c8d8330718061da549f32 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 15:12:32 +0200 Subject: [PATCH 02/22] Add error module --- libimagannotation/src/error.rs | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 libimagannotation/src/error.rs diff --git a/libimagannotation/src/error.rs b/libimagannotation/src/error.rs new file mode 100644 index 00000000..7a750c34 --- /dev/null +++ b/libimagannotation/src/error.rs @@ -0,0 +1,36 @@ +// +// 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 +// + +generate_error_module!( + generate_error_types!(AnnotationError, AnnotationErrorKind, + StoreReadError => "Store read error", + StoreWriteError => "Store write error", + StoreIdGenerationError => "Error generating StoreId object", + + LinkError => "Link error", + LinkingError => "Error while linking" + + ); +); + +pub use self::error::AnnotationError; +pub use self::error::AnnotationErrorKind; +pub use self::error::MapErrInto; + + From 4a2890f285a5106b52cb70360a3652fef8f28392 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 15:12:38 +0200 Subject: [PATCH 03/22] Add result module --- libimagannotation/src/result.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 libimagannotation/src/result.rs diff --git a/libimagannotation/src/result.rs b/libimagannotation/src/result.rs new file mode 100644 index 00000000..292fc0e5 --- /dev/null +++ b/libimagannotation/src/result.rs @@ -0,0 +1,26 @@ +// +// 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::result::Result as RResult; + +use error::AnnotationError; + +pub type Result = RResult; + + From f6d7d285640e7bfeb1e59d69a545c79e27e6ead0 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 15:12:52 +0200 Subject: [PATCH 04/22] Add first code dump for annotation module --- libimagannotation/src/annotation.rs | 75 +++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 libimagannotation/src/annotation.rs diff --git a/libimagannotation/src/annotation.rs b/libimagannotation/src/annotation.rs new file mode 100644 index 00000000..33dd3644 --- /dev/null +++ b/libimagannotation/src/annotation.rs @@ -0,0 +1,75 @@ +// +// 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::store::Store; +use libimagstore::store::FileLockEntry; +use libimagstore::storeid::StoreId; + +use result::Result; +use error::AnnotationErrorKind as AEK; + +use module_path::ModuleEntryPath; + +pub trait Annotateable { + + /// Add an annotation to `Self`, that is a `FileLockEntry` which is linked to `Self` (link as in + /// libimagentrylink). + /// + /// This `Annotation` is stored in the Store itself. + fn annotate(&self, store: &Store) -> Result { + self.annotate_with_path_generator(store, DefaultAnnotationPathGenerator::new()) + } + + /// Add an annotation to `Self`, that is a `FileLockEntry` which is linked to `Self` (link as in + /// libimagentrylink). + /// + /// This `Annotation` is stored in the Store itself. + /// + /// The `pg` is a AnnotationPathGenerator object which is used to generate a StoreId + fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationPathGenerator) -> Result; + +} + +/// A AnnotationPathGenerator generates a unique path for the annotation to be generated. +pub trait AnnotationPathGenerator { + fn generate_annotation_path(&self) -> Result; +} + +/// The DefaultAnnotationPathGenerator generates unique StoreIds for Annotations, where the +/// collection the annotations are stored in is `/annotation/`. +pub struct DefaultAnnotationPathGenerator; + +impl AnnotationPathGenerator for DefaultAnnotationPathGenerator { + + fn generate_annotation_path(&self) -> Result { + let id = Uuid::new_v4(); + ModuleEntryPath::new(format!("{}", id)).map_err_into(AEK::StoreIdGenerationError) + } + +} + +pub struct Annotation<'a>(FileLockEntry<'a>); + +impl Annotateable for FileLockEntry { + + fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationPathGenerator) + -> Result + { + } +} From 8f4c712cdb2a31fc810d7109f10084cc89223b79 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 15:13:01 +0200 Subject: [PATCH 05/22] Add dependencies --- libimagannotation/Cargo.toml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libimagannotation/Cargo.toml b/libimagannotation/Cargo.toml index d4268e9e..d4745ca6 100644 --- a/libimagannotation/Cargo.toml +++ b/libimagannotation/Cargo.toml @@ -1,6 +1,20 @@ [package] name = "libimagannotation" -version = "0.1.0" +version = "0.2.0" authors = ["Matthias Beyer "] [dependencies] +uuid = { version = "0.3.1", features = ["v4"] } + +[dependencies.libimagstore] +path = "../libimagstore" + +[dependencies.libimagerror] +path = "../libimagerror" + +[dependencies.libimagentrylink] +path = "../libimagentrylink" + +[dependencies.libimagutil] +path = "../libimagutil" + From 956b3dbf3800497d6c18e0206baca0543963c71e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 15:13:08 +0200 Subject: [PATCH 06/22] Add lib module --- libimagannotation/src/lib.rs | 38 ++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index cdfbe1aa..90eed07d 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -1,6 +1,32 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - } -} +// +// 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 +// + +extern crate uuid; + +#[macro_use] extern crate libimagerror; +#[macro_use] extern crate libimagstore; +extern crate libimaglink; +extern crate libimagutil; + +module_entry_path_mod!("annotation"); + +pub mod annotation; +pub mod error; +pub mod result; + From cb45c91fa523bd71fd38b3cab3e67c47eaad0c2a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 15:57:16 +0200 Subject: [PATCH 07/22] Add impl Annotateable::annotate_with_path_generator() for FileLockEntry --- libimagannotation/src/annotation.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libimagannotation/src/annotation.rs b/libimagannotation/src/annotation.rs index 33dd3644..5e2ad2fc 100644 --- a/libimagannotation/src/annotation.rs +++ b/libimagannotation/src/annotation.rs @@ -71,5 +71,13 @@ impl Annotateable for FileLockEntry { fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationPathGenerator) -> Result { + pb.generate_annotation_path() + .and_then(|id| store.create(id).map_err_into(AEK::StoreWriteError)) + .and_then(|mut fle| { + self.add_internal_link(&mut fle) + .map_err_into(AEK::LinkingError) + .map(|_| fle) + }) + .map(Annotation) } } From 3f5aded44643286f8ccb8d4c094601aee872081b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 16:05:39 +0200 Subject: [PATCH 08/22] Add Annotateable::annotations() --- libimagannotation/src/annotation.rs | 25 +++++++++++++++++++++++++ libimagannotation/src/lib.rs | 4 +++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/libimagannotation/src/annotation.rs b/libimagannotation/src/annotation.rs index 5e2ad2fc..3d0d11e9 100644 --- a/libimagannotation/src/annotation.rs +++ b/libimagannotation/src/annotation.rs @@ -44,6 +44,11 @@ pub trait Annotateable { /// The `pg` is a AnnotationPathGenerator object which is used to generate a StoreId fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationPathGenerator) -> Result; + /// List annotations of a Annotateable + /// + /// This lists only annotations that are generated via the `DefaultAnnotationPathGenerator` + fn annotations(&self) -> Result>; + } /// A AnnotationPathGenerator generates a unique path for the annotation to be generated. @@ -80,4 +85,24 @@ impl Annotateable for FileLockEntry { }) .map(Annotation) } + + /// Get the annotations of a FileLockEntry + /// + /// Returns the pathes to the annotations, not the annotations itself. + fn annotations(&self) -> Result> { + self.get_internal_links() + .map_err_into(AEK::LinkError) + .map(|v| v.iter_into() + .filter(|id| id.components() + .next() + .map(|fst| match fst { + Component::Normal(ref s) => s == ANNOTATION_COLLECTION_NAME, + _ => false, + }) + .unwrap_or(false) + ) + .collect::>(); + ) + } + } diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index 90eed07d..369f2515 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -24,7 +24,9 @@ extern crate uuid; extern crate libimaglink; extern crate libimagutil; -module_entry_path_mod!("annotation"); +static ANNOTATION_COLLECTION_NAME : &str = "annotation"; + +module_entry_path_mod!(ANNOTATION_COLLECTION_NAME); pub mod annotation; pub mod error; From 91d1c61518c02150557786fad73c80f621d13082 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 16:11:10 +0200 Subject: [PATCH 09/22] Add Annotateable::remove_annotation*() --- libimagannotation/src/annotation.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libimagannotation/src/annotation.rs b/libimagannotation/src/annotation.rs index 3d0d11e9..01b78db1 100644 --- a/libimagannotation/src/annotation.rs +++ b/libimagannotation/src/annotation.rs @@ -49,6 +49,13 @@ pub trait Annotateable { /// This lists only annotations that are generated via the `DefaultAnnotationPathGenerator` fn annotations(&self) -> Result>; + /// Remove an annotation by its ID + fn remove_annotation(&mut self, ann_id: &str) -> Result<()>; + + /// Remove an annotation and remove the annotation object from the store, if there's no more + /// link to it. + fn remove_annotation_with_gc(&mut self, ann_id: &str, store: &Store) -> Result<()>; + } /// A AnnotationPathGenerator generates a unique path for the annotation to be generated. @@ -105,4 +112,15 @@ impl Annotateable for FileLockEntry { ) } + /// Remove an annotation by its ID + fn remove_annotation(&mut self, ann_id: &str) -> Result<()> { + unimplemented!() + } + + /// Remove an annotation and remove the annotation object from the store, if there's no more + /// link to it. + fn remove_annotation_with_gc(&mut self, ann_id: &str, store: &Store) -> Result<()> { + unimplemented!() + } + } From fae6190cbe4d094fe26dee9b72e6de43181c7cc2 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 16:24:57 +0200 Subject: [PATCH 10/22] Add dependency --- libimagannotation/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/libimagannotation/Cargo.toml b/libimagannotation/Cargo.toml index d4745ca6..2e4e3882 100644 --- a/libimagannotation/Cargo.toml +++ b/libimagannotation/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Matthias Beyer "] [dependencies] uuid = { version = "0.3.1", features = ["v4"] } +lazy_static = "0.1.15" [dependencies.libimagstore] path = "../libimagstore" From bf4a5cda44d7b749ae25c7a333a2f581462e7558 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 16:26:39 +0200 Subject: [PATCH 11/22] Export module entry path string --- libimagnotes/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libimagnotes/src/lib.rs b/libimagnotes/src/lib.rs index 10ef952b..44460736 100644 --- a/libimagnotes/src/lib.rs +++ b/libimagnotes/src/lib.rs @@ -43,7 +43,9 @@ extern crate libimagrt; extern crate libimagentryedit; extern crate libimagentrytag; -module_entry_path_mod!("notes"); +pub static MODULE_ENTRY_PATH_NAME: &'static str = "notes"; + +module_entry_path_mod!(MODULE_ENTRY_PATH_NAME); pub mod error; pub mod note; From 1f745af0d8039aeeebb6e8f5adf961ff9e2ed5e2 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 16:26:46 +0200 Subject: [PATCH 12/22] Add dependency --- libimagannotation/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libimagannotation/Cargo.toml b/libimagannotation/Cargo.toml index 2e4e3882..963b9ace 100644 --- a/libimagannotation/Cargo.toml +++ b/libimagannotation/Cargo.toml @@ -10,6 +10,9 @@ lazy_static = "0.1.15" [dependencies.libimagstore] path = "../libimagstore" +[dependencies.libimagnotes] +path = "../libimagnotes" + [dependencies.libimagerror] path = "../libimagerror" From c2f68a94c1b1865eec94e27454b030b25c098e36 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 13 Oct 2016 16:27:01 +0200 Subject: [PATCH 13/22] Switch to use libimagnotes --- libimagannotation/src/annotation.rs | 50 +++++++++++++---------------- libimagannotation/src/lib.rs | 4 +-- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/libimagannotation/src/annotation.rs b/libimagannotation/src/annotation.rs index 01b78db1..9ca26ad0 100644 --- a/libimagannotation/src/annotation.rs +++ b/libimagannotation/src/annotation.rs @@ -20,6 +20,7 @@ use libimagstore::store::Store; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreId; +use libimagnotes::note::Note; use result::Result; use error::AnnotationErrorKind as AEK; @@ -33,7 +34,7 @@ pub trait Annotateable { /// /// This `Annotation` is stored in the Store itself. fn annotate(&self, store: &Store) -> Result { - self.annotate_with_path_generator(store, DefaultAnnotationPathGenerator::new()) + self.annotate_with_path_generator(store, DefaultAnnotationNameGenerator::new()) } /// Add an annotation to `Self`, that is a `FileLockEntry` which is linked to `Self` (link as in @@ -41,12 +42,12 @@ pub trait Annotateable { /// /// This `Annotation` is stored in the Store itself. /// - /// The `pg` is a AnnotationPathGenerator object which is used to generate a StoreId - fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationPathGenerator) -> Result; + /// The `pg` is a AnnotationNameGenerator object which is used to generate a StoreId + fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationNameGenerator) -> Result; /// List annotations of a Annotateable /// - /// This lists only annotations that are generated via the `DefaultAnnotationPathGenerator` + /// This lists only annotations that are generated via the `DefaultAnnotationNameGenerator` fn annotations(&self) -> Result>; /// Remove an annotation by its ID @@ -58,33 +59,32 @@ pub trait Annotateable { } -/// A AnnotationPathGenerator generates a unique path for the annotation to be generated. -pub trait AnnotationPathGenerator { - fn generate_annotation_path(&self) -> Result; +/// A AnnotationNameGenerator generates a unique path for the annotation to be generated. +pub trait AnnotationNameGenerator { + fn generate_annotation_path(&self) -> Result; } -/// The DefaultAnnotationPathGenerator generates unique StoreIds for Annotations, where the +/// The DefaultAnnotationNameGenerator generates unique StoreIds for Annotations, where the /// collection the annotations are stored in is `/annotation/`. -pub struct DefaultAnnotationPathGenerator; +pub struct DefaultAnnotationNameGenerator; -impl AnnotationPathGenerator for DefaultAnnotationPathGenerator { +impl AnnotationNameGenerator for DefaultAnnotationNameGenerator { - fn generate_annotation_path(&self) -> Result { - let id = Uuid::new_v4(); - ModuleEntryPath::new(format!("{}", id)).map_err_into(AEK::StoreIdGenerationError) + fn generate_annotation_path(&self) -> Result { + Ok(format!("{}/{}", MODULE_ENTRY_PATH_NAME, Uuid::new_v4())) } } -pub struct Annotation<'a>(FileLockEntry<'a>); +pub struct Annotation<'a>(Note<'a>); impl Annotateable for FileLockEntry { - fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationPathGenerator) + fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationNameGenerator) -> Result { pb.generate_annotation_path() - .and_then(|id| store.create(id).map_err_into(AEK::StoreWriteError)) + .and_then(|name| Note::new(store, name, String::new()).map_err_into(AEK::StoreWriteError)) .and_then(|mut fle| { self.add_internal_link(&mut fle) .map_err_into(AEK::LinkingError) @@ -97,19 +97,15 @@ impl Annotateable for FileLockEntry { /// /// Returns the pathes to the annotations, not the annotations itself. fn annotations(&self) -> Result> { + lazy_static! { + static ref pb : PathBuf = PathBuf::from(format!("{}/{}", + libimagnotes::MODULE_ENTRY_PATH_NAME, + MODULE_ENTRY_PATH_NAME)); + }; + self.get_internal_links() .map_err_into(AEK::LinkError) - .map(|v| v.iter_into() - .filter(|id| id.components() - .next() - .map(|fst| match fst { - Component::Normal(ref s) => s == ANNOTATION_COLLECTION_NAME, - _ => false, - }) - .unwrap_or(false) - ) - .collect::>(); - ) + .map(|v| v.iter_into().filter(|id| id.local().starts_with(pb)).collect()) } /// Remove an annotation by its ID diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index 369f2515..726349e8 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -24,9 +24,9 @@ extern crate uuid; extern crate libimaglink; extern crate libimagutil; -static ANNOTATION_COLLECTION_NAME : &str = "annotation"; +pub static MODULE_ENTRY_PATH_NAME: &'static str = "annotation"; -module_entry_path_mod!(ANNOTATION_COLLECTION_NAME); +module_entry_path_mod!(MODULE_ENTRY_PATH_NAME); pub mod annotation; pub mod error; From cded7b3a3dc5d59c2f81cbd32959aa2cfa89ec12 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:14:57 +0100 Subject: [PATCH 14/22] Revert "Export module entry path string" This reverts commit bf4a5cda44d7b749ae25c7a333a2f581462e7558. --- libimagnotes/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libimagnotes/src/lib.rs b/libimagnotes/src/lib.rs index 44460736..10ef952b 100644 --- a/libimagnotes/src/lib.rs +++ b/libimagnotes/src/lib.rs @@ -43,9 +43,7 @@ extern crate libimagrt; extern crate libimagentryedit; extern crate libimagentrytag; -pub static MODULE_ENTRY_PATH_NAME: &'static str = "notes"; - -module_entry_path_mod!(MODULE_ENTRY_PATH_NAME); +module_entry_path_mod!("notes"); pub mod error; pub mod note; From b71e68aee2b73f28e69387035e3c634d5bd6a0cc Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:15:57 +0100 Subject: [PATCH 15/22] Put libimagannotation into workspace --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 6a2adae4..e2033577 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "imag-store", "imag-tag", "imag-view", + "libimagannotation", "libimagentryedit", "libimagentryfilter", "libimagentrylink", From df562b48807b7939bae4a1ede7c876affdf98787 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:16:20 +0100 Subject: [PATCH 16/22] Fix dependency name --- libimagannotation/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index 726349e8..80b8afda 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -21,7 +21,7 @@ extern crate uuid; #[macro_use] extern crate libimagerror; #[macro_use] extern crate libimagstore; -extern crate libimaglink; +extern crate libimagentrylink; extern crate libimagutil; pub static MODULE_ENTRY_PATH_NAME: &'static str = "annotation"; From ff33c49ea56d82c3cc9bb80ecf36e1a20083486d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:21:53 +0100 Subject: [PATCH 17/22] Add dependency: toml --- libimagannotation/Cargo.toml | 1 + libimagannotation/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/libimagannotation/Cargo.toml b/libimagannotation/Cargo.toml index 963b9ace..4d15b2df 100644 --- a/libimagannotation/Cargo.toml +++ b/libimagannotation/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Matthias Beyer "] [dependencies] uuid = { version = "0.3.1", features = ["v4"] } lazy_static = "0.1.15" +toml = "0.2.*" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index 80b8afda..40654808 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -18,6 +18,7 @@ // extern crate uuid; +extern crate toml; #[macro_use] extern crate libimagerror; #[macro_use] extern crate libimagstore; From c773519281625b51ee7b6ba548833d99779b15cb Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:22:06 +0100 Subject: [PATCH 18/22] Rewrite error module --- libimagannotation/src/error.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libimagannotation/src/error.rs b/libimagannotation/src/error.rs index 7a750c34..d2ef789b 100644 --- a/libimagannotation/src/error.rs +++ b/libimagannotation/src/error.rs @@ -19,13 +19,11 @@ generate_error_module!( generate_error_types!(AnnotationError, AnnotationErrorKind, - StoreReadError => "Store read error", - StoreWriteError => "Store write error", - StoreIdGenerationError => "Error generating StoreId object", - - LinkError => "Link error", - LinkingError => "Error while linking" + StoreReadError => "Store read error", + StoreWriteError => "Store write error", + LinkingError => "Error while linking", + HeaderWriteError => "Couldn't write Header for annotation" ); ); @@ -33,4 +31,3 @@ pub use self::error::AnnotationError; pub use self::error::AnnotationErrorKind; pub use self::error::MapErrInto; - From ae2253a7b9d4696da48d7f7c0e46405cc1fc2fd4 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:22:46 +0100 Subject: [PATCH 19/22] Add libimagnotes extern crate, remove module entry path mod generation --- libimagannotation/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index 40654808..4d050613 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -23,12 +23,9 @@ extern crate toml; #[macro_use] extern crate libimagerror; #[macro_use] extern crate libimagstore; extern crate libimagentrylink; +extern crate libimagnotes; extern crate libimagutil; -pub static MODULE_ENTRY_PATH_NAME: &'static str = "annotation"; - -module_entry_path_mod!(MODULE_ENTRY_PATH_NAME); - pub mod annotation; pub mod error; pub mod result; From 0fbc61efa65cf09985878bd54d5d045f4c6d6eb8 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:22:57 +0100 Subject: [PATCH 20/22] Rewrite annotation helper --- libimagannotation/src/annotation.rs | 118 ++++++++-------------------- 1 file changed, 33 insertions(+), 85 deletions(-) diff --git a/libimagannotation/src/annotation.rs b/libimagannotation/src/annotation.rs index 9ca26ad0..698773cb 100644 --- a/libimagannotation/src/annotation.rs +++ b/libimagannotation/src/annotation.rs @@ -17,106 +17,54 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use libimagstore::store::Store; +use std::path::PathBuf; + +use toml::Value; + +use libimagstore::store::Entry; use libimagstore::store::FileLockEntry; -use libimagstore::storeid::StoreId; -use libimagnotes::note::Note; +use libimagstore::store::Store; +use libimagstore::toml_ext::TomlValueExt; +use libimagentrylink::internal::InternalLinker; +use libimagerror::into::IntoError; use result::Result; use error::AnnotationErrorKind as AEK; - -use module_path::ModuleEntryPath; +use error::MapErrInto; pub trait Annotateable { /// Add an annotation to `Self`, that is a `FileLockEntry` which is linked to `Self` (link as in /// libimagentrylink). /// - /// This `Annotation` is stored in the Store itself. - fn annotate(&self, store: &Store) -> Result { - self.annotate_with_path_generator(store, DefaultAnnotationNameGenerator::new()) - } - - /// Add an annotation to `Self`, that is a `FileLockEntry` which is linked to `Self` (link as in - /// libimagentrylink). - /// - /// This `Annotation` is stored in the Store itself. - /// - /// The `pg` is a AnnotationNameGenerator object which is used to generate a StoreId - fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationNameGenerator) -> Result; - - /// List annotations of a Annotateable - /// - /// This lists only annotations that are generated via the `DefaultAnnotationNameGenerator` - fn annotations(&self) -> Result>; - - /// Remove an annotation by its ID - fn remove_annotation(&mut self, ann_id: &str) -> Result<()>; - - /// Remove an annotation and remove the annotation object from the store, if there's no more - /// link to it. - fn remove_annotation_with_gc(&mut self, ann_id: &str, store: &Store) -> Result<()>; + /// A new annotation also has the field `annotation.is_annotation` set to `true`. + fn annotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result>; } -/// A AnnotationNameGenerator generates a unique path for the annotation to be generated. -pub trait AnnotationNameGenerator { - fn generate_annotation_path(&self) -> Result; -} +impl Annotateable for Entry { -/// The DefaultAnnotationNameGenerator generates unique StoreIds for Annotations, where the -/// collection the annotations are stored in is `/annotation/`. -pub struct DefaultAnnotationNameGenerator; - -impl AnnotationNameGenerator for DefaultAnnotationNameGenerator { - - fn generate_annotation_path(&self) -> Result { - Ok(format!("{}/{}", MODULE_ENTRY_PATH_NAME, Uuid::new_v4())) - } - -} - -pub struct Annotation<'a>(Note<'a>); - -impl Annotateable for FileLockEntry { - - fn annotate_with_path_generator(&self, store: &Store, pg: &AnnotationNameGenerator) - -> Result - { - pb.generate_annotation_path() - .and_then(|name| Note::new(store, name, String::new()).map_err_into(AEK::StoreWriteError)) - .and_then(|mut fle| { - self.add_internal_link(&mut fle) - .map_err_into(AEK::LinkingError) - .map(|_| fle) + fn annotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result> { + store.retrieve(PathBuf::from(ann_name)) + .map_err_into(AEK::StoreWriteError) + .and_then(|mut anno| { + anno.get_header_mut() + .insert("annotation.is_annotation", Value::Boolean(true)) + .map_err_into(AEK::StoreWriteError) + .and_then(|succeeded| { + if succeeded { + Ok(anno) + } else { + Err(AEK::HeaderWriteError.into_error()) + } + }) + }) + .and_then(|mut anno| { + anno.add_internal_link(self) + .map_err_into(AEK::LinkingError) + .map(|_| anno) }) - .map(Annotation) - } - - /// Get the annotations of a FileLockEntry - /// - /// Returns the pathes to the annotations, not the annotations itself. - fn annotations(&self) -> Result> { - lazy_static! { - static ref pb : PathBuf = PathBuf::from(format!("{}/{}", - libimagnotes::MODULE_ENTRY_PATH_NAME, - MODULE_ENTRY_PATH_NAME)); - }; - - self.get_internal_links() - .map_err_into(AEK::LinkError) - .map(|v| v.iter_into().filter(|id| id.local().starts_with(pb)).collect()) - } - - /// Remove an annotation by its ID - fn remove_annotation(&mut self, ann_id: &str) -> Result<()> { - unimplemented!() - } - - /// Remove an annotation and remove the annotation object from the store, if there's no more - /// link to it. - fn remove_annotation_with_gc(&mut self, ann_id: &str, store: &Store) -> Result<()> { - unimplemented!() } } + From fdbd1cea6421088c1d098bca4eb3e9c5aa5bbb66 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 13:23:17 +0100 Subject: [PATCH 21/22] Rename module --- libimagannotation/src/{annotation.rs => annotateable.rs} | 0 libimagannotation/src/lib.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename libimagannotation/src/{annotation.rs => annotateable.rs} (100%) diff --git a/libimagannotation/src/annotation.rs b/libimagannotation/src/annotateable.rs similarity index 100% rename from libimagannotation/src/annotation.rs rename to libimagannotation/src/annotateable.rs diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index 4d050613..db3f9ace 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -26,7 +26,7 @@ extern crate libimagentrylink; extern crate libimagnotes; extern crate libimagutil; -pub mod annotation; +pub mod annotateable; pub mod error; pub mod result; From 5034540595b974305701eca2a1c7153f7af4e8ec Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Feb 2017 14:11:32 +0100 Subject: [PATCH 22/22] Add annotation entry fetcher module --- libimagannotation/src/annotation_fetcher.rs | 116 ++++++++++++++++++++ libimagannotation/src/error.rs | 4 +- libimagannotation/src/lib.rs | 1 + 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 libimagannotation/src/annotation_fetcher.rs diff --git a/libimagannotation/src/annotation_fetcher.rs b/libimagannotation/src/annotation_fetcher.rs new file mode 100644 index 00000000..6c5ac298 --- /dev/null +++ b/libimagannotation/src/annotation_fetcher.rs @@ -0,0 +1,116 @@ +// +// 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::store::Entry; +use libimagstore::store::Store; +use libimagentrylink::internal::InternalLinker; +use libimagnotes::note::Note; +use libimagnotes::note::NoteIterator; +use libimagstore::storeid::StoreIdIterator; + +use result::Result; +use error::AnnotationErrorKind as AEK; +use error::MapErrInto; + +use self::iter::*; + +pub trait AnnotationFetcher<'a> { + + fn all_annotations(&'a self) -> Result>; + + fn annotations_for_entry(&'a self, entry: &Entry) -> Result>; + +} + +impl<'a> AnnotationFetcher<'a> for Store { + + /// Wrapper around `Note::all_notes()` of `libimagnotes` which filters out normal notes and + /// leaves only annotations in the iterator. + fn all_annotations(&'a self) -> Result> { + Note::all_notes(self) + .map(|iter| AnnotationIter::new(iter)) + .map_err_into(AEK::StoreReadError) + } + + /// Get all annotations (in an iterator) for an entry + /// + /// Internally, this fetches the links of the entry, fetches all the entries behind the links + /// and filters them for annotations. + /// + /// This might result in some heavy IO operations if a lot of stuff is linked to a single + /// entry, but should normally be not that heavy. + fn annotations_for_entry(&'a self, entry: &Entry) -> Result> { + entry.get_internal_links() + .map_err_into(AEK::StoreReadError) + .map(Box::new) + .map(|iter| StoreIdIterator::new(iter)) + .map(|iter| NoteIterator::new(self, iter)) + .map(|iter| AnnotationIter::new(iter)) + } + +} + +pub mod iter { + use toml::Value; + + use libimagstore::toml_ext::TomlValueExt; + use libimagerror::into::IntoError; + use libimagnotes::note::Note; + use libimagnotes::note::NoteIterator; + + use result::Result; + use error::AnnotationErrorKind as AEK; + use error::MapErrInto; + + #[derive(Debug)] + pub struct AnnotationIter<'a>(NoteIterator<'a>); + + impl<'a> AnnotationIter<'a> { + + pub fn new(noteiter: NoteIterator<'a>) -> AnnotationIter<'a> { + AnnotationIter(noteiter) + } + + } + + impl<'a> Iterator for AnnotationIter<'a> { + type Item = Result>; + + fn next(&mut self) -> Option>> { + loop { + match self.0.next() { + Some(Ok(note)) => { + let hdr = note.get_header().read("annotation.is_annotation"); + match hdr { + Ok(None) => continue, // not an annotation + Ok(Some(Value::Boolean(true))) => return Some(Ok(note)), + Ok(Some(_)) => return Some(Err(AEK::HeaderTypeError.into_error())), + Err(e) => return Some(Err(e).map_err_into(AEK::HeaderReadError)), + } + }, + Some(Err(e)) => return Some(Err(e).map_err_into(AEK::StoreReadError)), + None => return None, // iterator consumed + } + } + } + + } + +} + diff --git a/libimagannotation/src/error.rs b/libimagannotation/src/error.rs index d2ef789b..25fc0048 100644 --- a/libimagannotation/src/error.rs +++ b/libimagannotation/src/error.rs @@ -23,7 +23,9 @@ generate_error_module!( StoreWriteError => "Store write error", LinkingError => "Error while linking", - HeaderWriteError => "Couldn't write Header for annotation" + HeaderWriteError => "Couldn't write Header for annotation", + HeaderReadError => "Couldn't read Header of Entry", + HeaderTypeError => "Header field has unexpected type" ); ); diff --git a/libimagannotation/src/lib.rs b/libimagannotation/src/lib.rs index db3f9ace..0cb4e779 100644 --- a/libimagannotation/src/lib.rs +++ b/libimagannotation/src/lib.rs @@ -27,6 +27,7 @@ extern crate libimagnotes; extern crate libimagutil; pub mod annotateable; +pub mod annotation_fetcher; pub mod error; pub mod result;