From 67410b3ad2c06abef416c217f4908ddf217dbb86 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 25 Nov 2017 16:10:07 +0100 Subject: [PATCH 1/4] Implement iter extension for all iterators over StoreId --- lib/core/libimagstore/src/iter.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/core/libimagstore/src/iter.rs b/lib/core/libimagstore/src/iter.rs index b351a785..2bff1738 100644 --- a/lib/core/libimagstore/src/iter.rs +++ b/lib/core/libimagstore/src/iter.rs @@ -27,14 +27,13 @@ macro_rules! mk_iterator_mod { fun = $fun:expr } => { pub mod $modname { - use storeid::StoreIdIterator; use storeid::StoreId; #[allow(unused_imports)] use store::FileLockEntry; use store::Store; use error::Result; - pub struct $itername<'a>(StoreIdIterator, &'a Store); + pub struct $itername<'a>(Box>, &'a Store); impl<'a> Iterator for $itername<'a> { type Item = Result<$yield>; @@ -48,11 +47,14 @@ macro_rules! mk_iterator_mod { fn $extfnname(self, store: &'a Store) -> $itername<'a>; } - impl<'a> $extname<'a> for StoreIdIterator { + impl<'a, I> $extname<'a> for I + where I: Iterator + 'static + { fn $extfnname(self, store: &'a Store) -> $itername<'a> { - $itername(self, store) + $itername(Box::new(self), store) } } + } } } From 0870665668dfa217e5b35c08abcdcf5d75083e0e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 25 Nov 2017 16:50:39 +0100 Subject: [PATCH 2/4] Add iterator extension for iterators over Result --- lib/core/libimagstore/src/iter.rs | 190 +++++++++++++++++++++++++----- 1 file changed, 159 insertions(+), 31 deletions(-) diff --git a/lib/core/libimagstore/src/iter.rs b/lib/core/libimagstore/src/iter.rs index 2bff1738..8f8a5441 100644 --- a/lib/core/libimagstore/src/iter.rs +++ b/lib/core/libimagstore/src/iter.rs @@ -17,7 +17,105 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // +macro_rules! mk_iterator { + { + modname = $modname:ident, + itername = $itername:ident, + iteryield = $yield:ty, + extname = $extname:ident, + extfnname = $extfnname:ident, + fun = $fun:expr + } => { + use storeid::StoreId; + #[allow(unused_imports)] + use store::FileLockEntry; + use store::Store; + use error::Result; + + pub struct $itername<'a>(Box>, &'a Store); + + impl<'a> Iterator for $itername<'a> { + type Item = Result<$yield>; + + fn next(&mut self) -> Option { + self.0.next().map(|id| $fun(id, self.1)) + } + } + + pub trait $extname<'a> { + fn $extfnname(self, store: &'a Store) -> $itername<'a>; + } + + impl<'a, I> $extname<'a> for I + where I: Iterator + 'static + { + fn $extfnname(self, store: &'a Store) -> $itername<'a> { + $itername(Box::new(self), store) + } + } + } +} + +use error::StoreError; + +pub enum ExtensionError { + Forwarded(E), + StoreError(StoreError) +} + macro_rules! mk_iterator_mod { + { + modname = $modname:ident, + itername = $itername:ident, + iteryield = $yield:ty, + extname = $extname:ident, + extfnname = $extfnname:ident, + fun = $fun:expr, + resultitername = $resultitername:ident, + resultextname = $resultextname:ident + } => { + pub mod $modname { + mk_iterator! { + modname = $modname, + itername = $itername, + iteryield = $yield, + extname = $extname, + extfnname = $extfnname, + fun = $fun + } + + use std::result::Result as RResult; + + pub struct $resultitername<'a, I>(I, &'a Store); + + impl<'a, I, E> Iterator for $resultitername<'a, I> + where I: Iterator> + { + type Item = RResult<$yield, $crate::iter::ExtensionError>; + + fn next(&mut self) -> Option { + match self.0.next() { + Some(Ok(sid)) => Some($fun(sid, self.1).map_err($crate::iter::ExtensionError::StoreError)), + Some(Err(e)) => Some(Err($crate::iter::ExtensionError::Forwarded(e))), + None => None, + } + } + } + + pub trait $resultextname<'a> : Iterator { + fn $extfnname(self, store: &'a Store) -> $resultitername<'a, Self> + where Self: Sized + { + $resultitername(self, store) + } + } + + impl<'a, I> $resultextname<'a> for I + where I: Iterator + { /* empty */ } + } + }; + { modname = $modname:ident, itername = $itername:ident, @@ -27,34 +125,14 @@ macro_rules! mk_iterator_mod { fun = $fun:expr } => { pub mod $modname { - use storeid::StoreId; - #[allow(unused_imports)] - use store::FileLockEntry; - use store::Store; - use error::Result; - - pub struct $itername<'a>(Box>, &'a Store); - - impl<'a> Iterator for $itername<'a> { - type Item = Result<$yield>; - - fn next(&mut self) -> Option { - self.0.next().map(|id| $fun(id, self.1)) - } + mk_iterator! { + modname = $modname, + itername = $itername, + iteryield = $yield, + extname = $extname, + extfnname = $extfnname, + fun = $fun } - - pub trait $extname<'a> { - fn $extfnname(self, store: &'a Store) -> $itername<'a>; - } - - impl<'a, I> $extname<'a> for I - where I: Iterator + 'static - { - fn $extfnname(self, store: &'a Store) -> $itername<'a> { - $itername(Box::new(self), store) - } - } - } } } @@ -65,7 +143,9 @@ mk_iterator_mod! { iteryield = FileLockEntry<'a>, extname = StoreIdCreateIteratorExtension, extfnname = into_create_iter, - fun = |id: StoreId, store: &'a Store| store.create(id) + fun = |id: StoreId, store: &'a Store| store.create(id), + resultitername = StoreCreateResultIterator, + resultextname = StoreIdCreateResultIteratorExtension } mk_iterator_mod! { @@ -74,7 +154,9 @@ mk_iterator_mod! { iteryield = (), extname = StoreIdDeleteIteratorExtension, extfnname = into_delete_iter, - fun = |id: StoreId, store: &'a Store| store.delete(id) + fun = |id: StoreId, store: &'a Store| store.delete(id), + resultitername = StoreDeleteResultIterator, + resultextname = StoreIdDeleteResultIteratorExtension } mk_iterator_mod! { @@ -83,7 +165,9 @@ mk_iterator_mod! { iteryield = Option>, extname = StoreIdGetIteratorExtension, extfnname = into_get_iter, - fun = |id: StoreId, store: &'a Store| store.get(id) + fun = |id: StoreId, store: &'a Store| store.get(id), + resultitername = StoreGetResultIterator, + resultextname = StoreIdGetResultIteratorExtension } mk_iterator_mod! { @@ -92,6 +176,50 @@ mk_iterator_mod! { iteryield = FileLockEntry<'a>, extname = StoreIdRetrieveIteratorExtension, extfnname = into_retrieve_iter, - fun = |id: StoreId, store: &'a Store| store.retrieve(id) + fun = |id: StoreId, store: &'a Store| store.retrieve(id), + resultitername = StoreRetrieveResultIterator, + resultextname = StoreIdRetrieveResultIteratorExtension +} + +#[cfg(test)] +mod compile_test { + + // This module contains code to check whether this actually compiles the way we would like it to + // compile + + use store::Store; + use storeid::StoreId; + + #[allow(dead_code)] + fn store() -> Store { + unimplemented!() + } + + #[allow(dead_code)] + fn test_compile_get() { + use super::get::StoreIdGetIteratorExtension; + + let store = store(); + let _ = store + .entries() + .unwrap() + .into_get_iter(&store); + } + + #[allow(dead_code)] + fn test_compile_get_result() { + use super::get::StoreIdGetResultIteratorExtension; + + fn to_result(e: StoreId) -> Result { + Ok(e) + } + + let store = store(); + let _ = store + .entries() + .unwrap() + .map(to_result) + .into_get_iter(&store); + } } From d6e1994eebcb929fc000d70df43f1ad3d3410621 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 26 Nov 2017 14:16:20 +0100 Subject: [PATCH 3/4] Fix: Explicitely import only relevant trait --- bin/core/imag-diagnostics/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/core/imag-diagnostics/src/main.rs b/bin/core/imag-diagnostics/src/main.rs index 784d98ef..9f813055 100644 --- a/bin/core/imag-diagnostics/src/main.rs +++ b/bin/core/imag-diagnostics/src/main.rs @@ -46,7 +46,7 @@ use libimagrt::setup::generate_runtime_setup; use libimagerror::trace::MapErrTrace; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreId; -use libimagstore::iter::get::*; +use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagstore::error::StoreError as Error; use libimagentrylink::internal::*; From 46a8d373b3376db7f7d47f3b8657cb30f1e95036 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 25 Dec 2017 19:23:39 +0100 Subject: [PATCH 4/4] Allow dead code in whole module --- lib/core/libimagstore/src/iter.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/core/libimagstore/src/iter.rs b/lib/core/libimagstore/src/iter.rs index 8f8a5441..d42c92fc 100644 --- a/lib/core/libimagstore/src/iter.rs +++ b/lib/core/libimagstore/src/iter.rs @@ -182,6 +182,7 @@ mk_iterator_mod! { } #[cfg(test)] +#[allow(dead_code)] mod compile_test { // This module contains code to check whether this actually compiles the way we would like it to @@ -190,12 +191,10 @@ mod compile_test { use store::Store; use storeid::StoreId; - #[allow(dead_code)] fn store() -> Store { unimplemented!() } - #[allow(dead_code)] fn test_compile_get() { use super::get::StoreIdGetIteratorExtension; @@ -206,7 +205,6 @@ mod compile_test { .into_get_iter(&store); } - #[allow(dead_code)] fn test_compile_get_result() { use super::get::StoreIdGetResultIteratorExtension;