summaryrefslogtreecommitdiffstats
path: root/libimagentrylink
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2016-10-13 18:50:41 +0200
committerMatthias Beyer <mail@beyermatthias.de>2016-10-19 14:34:10 +0200
commit0eda8e2d0459f96aae9e5e59cf5b121d0234bf16 (patch)
treec424724f004732ab8e60b230d9d0bff1e0df0f3c /libimagentrylink
parent4ee505c6589e68c537e6c9cbee91b29eff9b855f (diff)
Initial add iterators for link library
Diffstat (limited to 'libimagentrylink')
-rw-r--r--libimagentrylink/src/internal.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/libimagentrylink/src/internal.rs b/libimagentrylink/src/internal.rs
index 3110ff79..9c7648ff 100644
--- a/libimagentrylink/src/internal.rs
+++ b/libimagentrylink/src/internal.rs
@@ -61,6 +61,9 @@ pub mod iter {
use toml::Value;
use itertools::Itertools;
+ use libimagstore::store::Store;
+ use libimagstore::store::FileLockEntry;
+
pub struct LinkIter(IntoIter<Link>);
impl LinkIter {
@@ -69,6 +72,14 @@ pub mod iter {
LinkIter(v.into_iter())
}
+ pub fn into_getter(self, store: &Store) -> GetIter {
+ GetIter(self.0, store)
+ }
+
+ pub fn into_deleter(self, store: &Store) -> DeleteIter {
+ DeleteIter(self.0, store)
+ }
+
}
impl Iterator for LinkIter {
@@ -104,6 +115,98 @@ pub mod iter {
}
}
+ /// An Iterator that `Store::get()`s the Entries from the store while consumed
+ pub struct GetIter<'a>(IntoIter<Link>, &'a Store);
+
+ impl<'a> GetIter<'a> {
+ fn new(i: IntoIter<Link>, store: &'a Store) -> GetIter<'a> {
+ GetIter(i, store)
+ }
+
+ /// Turn this iterator into a LinkGcIter, which `Store::delete()`s entries that are not
+ /// linked to any other entry.
+ pub fn remove_unlinked(self) -> RemoveUnlinkedIter<'a> {
+ RemoveUnlinkedIter(self)
+ }
+
+ pub fn store(&self) -> &Store {
+ self.1
+ }
+ }
+
+ impl<'a> Iterator for GetIter<'a> {
+ type Item = Result<FileLockEntry<'a>>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().and_then(|id| match self.1.get(id).map_err_into(LEK::StoreReadError) {
+ Ok(None) => None,
+ Ok(Some(x)) => Some(Ok(x)),
+ Err(e) => Some(Err(e)),
+ })
+ }
+
+ }
+
+ /// An Iterator that `Store::get()`s the Entries from the store while consumed
+ pub struct DeleteIter<'a>(IntoIter<Link>, &'a Store);
+
+ impl<'a> DeleteIter<'a> {
+ fn new(i: IntoIter<Link>, store: &'a Store) -> DeleteIter<'a> {
+ DeleteIter(i, store)
+ }
+ }
+
+ impl<'a> Iterator for DeleteIter<'a> {
+ type Item = Result<()>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|id| self.1.delete(id).map_err_into(LEK::StoreReadError))
+ }
+
+ }
+
+ /// An iterator that removes all Items from the iterator that are not linked anymore by calling
+ /// `Store::delete()` on them.
+ ///
+ /// It yields only items which are somehow linked to another entry
+ pub struct RemoveUnlinkedIter<'a>(GetIter<'a>);
+
+ impl<'a> Iterator for RemoveUnlinkedIter<'a> {
+ type Item = Result<FileLockEntry<'a>>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ use internal::InternalLinker;
+
+ loop {
+ match self.0.next() {
+ Some(Ok(fle)) => {
+ let links = match fle.get_internal_links().map_err_into(LEK::StoreReadError)
+ {
+ Err(e) => return Some(Err(e)),
+ Ok(links) => links,
+ };
+ if links.count() == 0 {
+ match self.0
+ .store()
+ .delete(fle.get_location().clone())
+ .map_err_into(LEK::StoreWriteError)
+ {
+ Ok(x) => x,
+ Err(e) => return Some(Err(e)),
+ }
+ } else {
+ return Some(Ok(fle));
+ }
+ },
+ Some(Err(e)) => return Some(Err(e)),
+ None => break,
+ }
+ }
+ None
+ }
+
+ }
+
}
impl InternalLinker for Entry {