diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2016-10-13 18:50:41 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2016-10-19 14:34:10 +0200 |
commit | 0eda8e2d0459f96aae9e5e59cf5b121d0234bf16 (patch) | |
tree | c424724f004732ab8e60b230d9d0bff1e0df0f3c /libimagentrylink | |
parent | 4ee505c6589e68c537e6c9cbee91b29eff9b855f (diff) |
Initial add iterators for link library
Diffstat (limited to 'libimagentrylink')
-rw-r--r-- | libimagentrylink/src/internal.rs | 103 |
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 { |