From d08c27e623b76f0ab87561da97ccb4678f48c953 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 1 May 2018 16:25:22 +0200 Subject: [PATCH] Rewrite StoreIdIterator extensions This patch reimplements the iterator extensions. As we iterate (in StoreIdIterator) over Result now anyways, we don't need the extensions for Result iterators anymore. This patch rewrites the extensions to be more simple in every way and generic over the error type in the iterator. All the errors have to do is implement From, which is what they do when linking the generated error types with error_chain to the libimagstore error types. --- lib/core/libimagstore/src/iter.rs | 168 +++++++-------------------- lib/core/libimagstore/src/storeid.rs | 10 +- 2 files changed, 51 insertions(+), 127 deletions(-) diff --git a/lib/core/libimagstore/src/iter.rs b/lib/core/libimagstore/src/iter.rs index 63100470..0e066b09 100644 --- a/lib/core/libimagstore/src/iter.rs +++ b/lib/core/libimagstore/src/iter.rs @@ -17,111 +17,7 @@ // 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>, &'a Store); - - impl<'a> $itername<'a> { - pub fn new(inner: Box> + 'a>, store: &'a Store) -> Self { - $itername(inner, 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> + 'a - { - 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, @@ -131,13 +27,47 @@ macro_rules! mk_iterator_mod { fun = $fun:expr } => { pub mod $modname { - mk_iterator! { - modname = $modname, - itername = $itername, - iteryield = $yield, - extname = $extname, - extfnname = $extfnname, - fun = $fun + use storeid::StoreId; + #[allow(unused_imports)] + use store::FileLockEntry; + use store::Store; + use error::StoreError; + use std::result::Result as RResult; + + pub struct $itername<'a, E>(Box> + 'a>, &'a Store) + where E: From; + + impl<'a, E> $itername<'a, E> + where E: From + { + pub fn new(inner: Box> + 'a>, store: &'a Store) -> Self { + $itername(inner, store) + } + } + + impl<'a, E> Iterator for $itername<'a, E> + where E: From + { + type Item = RResult<$yield, E>; + + fn next(&mut self) -> Option { + self.0.next().map(|id| $fun(id?, self.1).map_err(E::from)) + } + } + + pub trait $extname<'a, E> + where E: From + { + fn $extfnname(self, store: &'a Store) -> $itername<'a, E>; + } + + impl<'a, I, E> $extname<'a, E> for I + where I: Iterator> + 'a, + E: From + { + fn $extfnname(self, store: &'a Store) -> $itername<'a, E> { + $itername(Box::new(self), store) + } } } } @@ -149,9 +79,7 @@ mk_iterator_mod! { iteryield = FileLockEntry<'a>, extname = StoreIdCreateIteratorExtension, extfnname = into_create_iter, - fun = |id: StoreId, store: &'a Store| store.create(id), - resultitername = StoreCreateResultIterator, - resultextname = StoreIdCreateResultIteratorExtension + fun = |id: StoreId, store: &'a Store| store.create(id) } mk_iterator_mod! { @@ -160,9 +88,7 @@ mk_iterator_mod! { iteryield = (), extname = StoreIdDeleteIteratorExtension, extfnname = into_delete_iter, - fun = |id: StoreId, store: &'a Store| store.delete(id), - resultitername = StoreDeleteResultIterator, - resultextname = StoreIdDeleteResultIteratorExtension + fun = |id: StoreId, store: &'a Store| store.delete(id) } mk_iterator_mod! { @@ -171,9 +97,7 @@ mk_iterator_mod! { iteryield = Option>, extname = StoreIdGetIteratorExtension, extfnname = into_get_iter, - fun = |id: StoreId, store: &'a Store| store.get(id), - resultitername = StoreGetResultIterator, - resultextname = StoreIdGetResultIteratorExtension + fun = |id: StoreId, store: &'a Store| store.get(id) } mk_iterator_mod! { @@ -182,9 +106,7 @@ mk_iterator_mod! { iteryield = FileLockEntry<'a>, extname = StoreIdRetrieveIteratorExtension, extfnname = into_retrieve_iter, - fun = |id: StoreId, store: &'a Store| store.retrieve(id), - resultitername = StoreRetrieveResultIterator, - resultextname = StoreIdRetrieveResultIteratorExtension + fun = |id: StoreId, store: &'a Store| store.retrieve(id) } #[cfg(test)] diff --git a/lib/core/libimagstore/src/storeid.rs b/lib/core/libimagstore/src/storeid.rs index 80e1b35d..3d639797 100644 --- a/lib/core/libimagstore/src/storeid.rs +++ b/lib/core/libimagstore/src/storeid.rs @@ -287,6 +287,8 @@ impl<'a> Iterator for StoreIdIteratorWithStore<'a> { } } +use error::StoreError; + impl<'a> StoreIdIteratorWithStore<'a> { pub fn new(iter: Box>>, store: &'a Store) -> Self { @@ -300,7 +302,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// Transform the iterator into a StoreCreateIterator /// /// This immitates the API from `libimagstore::iter`. - pub fn into_create_iter(self) -> StoreCreateIterator<'a> { + pub fn into_create_iter(self) -> StoreCreateIterator<'a, StoreError> { StoreCreateIterator::new(Box::new(self.0), self.1) } @@ -308,7 +310,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// /// /// This immitates the API from `libimagstore::iter`. - pub fn into_delete_iter(self) -> StoreDeleteIterator<'a> { + pub fn into_delete_iter(self) -> StoreDeleteIterator<'a, StoreError> { StoreDeleteIterator::new(Box::new(self.0), self.1) } @@ -316,7 +318,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// /// /// This immitates the API from `libimagstore::iter`. - pub fn into_get_iter(self) -> StoreGetIterator<'a> { + pub fn into_get_iter(self) -> StoreGetIterator<'a, StoreError> { StoreGetIterator::new(Box::new(self.0), self.1) } @@ -324,7 +326,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// /// /// This immitates the API from `libimagstore::iter`. - pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a> { + pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a, StoreError> { StoreRetrieveIterator::new(Box::new(self.0), self.1) }