diff options
Diffstat (limited to 'lib/domain/libimagbookmark/src/store.rs')
-rw-r--r-- | lib/domain/libimagbookmark/src/store.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/lib/domain/libimagbookmark/src/store.rs b/lib/domain/libimagbookmark/src/store.rs new file mode 100644 index 00000000..9e3d4429 --- /dev/null +++ b/lib/domain/libimagbookmark/src/store.rs @@ -0,0 +1,107 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2019 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 failure::Fallible as Result; +use uuid::Uuid; +use url::Url; + +use libimagstore::store::Store; +use libimagstore::storeid::StoreId; +use libimagstore::store::FileLockEntry; +use libimagstore::iter::Entries; +use libimagentryurl::link::Link; +use libimagentryutil::isa::Is; + +use crate::bookmark::IsBookmark; +use crate::bookmark::Bookmark; + +pub trait BookmarkStore { + + fn add_bookmark<'a>(&'a self, url: Url) -> Result<(Uuid, FileLockEntry<'a>)>; + + fn get_bookmark_by_uuid<'a>(&'a self, uuid: &Uuid) -> Result<Option<FileLockEntry<'a>>>; + fn get_bookmark_by_id<'a>(&'a self, sid: StoreId) -> Result<Option<FileLockEntry<'a>>>; + + fn remove_bookmark_by_uuid(&self, uuid: &Uuid) -> Result<()>; + + fn remove_bookmark<'a>(&self, fle: FileLockEntry<'a>) -> Result<()>; + + fn all_bookmarks<'a>(&'a self) -> Result<Entries<'a>>; + +} + +impl BookmarkStore for Store { + fn add_bookmark<'a>(&'a self, url: Url) -> Result<(Uuid, FileLockEntry<'a>)> { + let uuid = uuid::Uuid::new_v4(); + id_for_uuid(&uuid) + .and_then(|id| self.create(id)) + .and_then(|mut entry| { + entry.set_isflag::<IsBookmark>()?; + entry.set_url(url).map(|_| (uuid, entry)) + }) + } + + fn get_bookmark_by_uuid<'a>(&'a self, uuid: &Uuid) -> Result<Option<FileLockEntry<'a>>> { + id_for_uuid(uuid).and_then(|id| self.get(id)) + } + + /// Get a bookmark by store id + /// + /// + /// # Warning + /// + /// Returns an error if the StoreId does not refer to an entry that is a Bookmark. + /// If you want to ignore these errors on this API level and handle these errors yourself, + /// use Store::get() + /// + fn get_bookmark_by_id<'a>(&'a self, sid: StoreId) -> Result<Option<FileLockEntry<'a>>> { + if let Some(entry) = self.get(sid)? { + if !entry.is_bookmark()? { + return Err(format_err!("Not a bookmark: {}", entry.get_location())); + } else { + Ok(Some(entry)) + } + } else { + Ok(None) + } + } + + fn remove_bookmark_by_uuid(&self, uuid: &Uuid) -> Result<()> { + id_for_uuid(uuid).and_then(|id| self.delete(id)) + } + + fn remove_bookmark<'a>(&self, fle: FileLockEntry<'a>) -> Result<()> { + if fle.is_bookmark()? { + let id = fle.get_location().clone(); + drop(fle); + self.delete(id) + } else { + Err(format_err!("Not a bookmark: {}", fle.get_location())) + } + } + + fn all_bookmarks<'a>(&'a self) -> Result<Entries<'a>> { + self.entries()?.in_collection("bookmark") + } +} + +fn id_for_uuid(uuid: &Uuid) -> Result<StoreId> { + crate::module_path::new_id(uuid.to_hyphenated().encode_lower(&mut Uuid::encode_buffer())) +} + |