From 0e20b25091a41b0092f127df15cd444fb78853ba Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 24 Oct 2019 17:39:38 +0200 Subject: [PATCH] Add extension traits for handling Result, E> conversion This extension traits help transforming Result, E> to Result or transforming an iterator over the former type to an iterator over the latter type. Should be moved to resiter of course, but we need to implement this first. Signed-off-by: Matthias Beyer --- lib/core/libimagerror/src/iter.rs | 46 +++++++++++++++++++++++++++++ lib/core/libimagerror/src/lib.rs | 1 + lib/core/libimagerror/src/result.rs | 38 ++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 lib/core/libimagerror/src/result.rs diff --git a/lib/core/libimagerror/src/iter.rs b/lib/core/libimagerror/src/iter.rs index 5a288321..1e7dbff9 100644 --- a/lib/core/libimagerror/src/iter.rs +++ b/lib/core/libimagerror/src/iter.rs @@ -128,3 +128,49 @@ impl TraceIterator for I where I: Iterator> {} + +/// Extension trait for doing +/// +/// ```ignore +/// Iterator, E>> -> Iterator> +/// ``` +/// +pub trait IterInnerOkOrElse + where T: Sized, + E: Sized, + Self: Iterator, E>> + Sized, + F: Fn() -> E, +{ + fn map_inner_ok_or_else(self, f: F) -> IterInnerOkOrElseImpl; +} + +pub struct IterInnerOkOrElseImpl(I, F) + where I: Iterator, E>> + Sized, + T: Sized, + E: Sized, + F: Fn() -> E; + +impl IterInnerOkOrElse for I + where I: Iterator, E>> + Sized, + T: Sized, + E: Sized, + F: Fn() -> E, +{ + fn map_inner_ok_or_else(self, f: F) -> IterInnerOkOrElseImpl { + IterInnerOkOrElseImpl(self, f) + } +} + +impl Iterator for IterInnerOkOrElseImpl + where I: Iterator, E>> + Sized, + T: Sized, + E: Sized, + F: Fn() -> E, +{ + type Item = Result; + + fn next(&mut self) -> Option { + self.0.next().map(|e| e.and_then(|opt| opt.ok_or_else(|| (self.1)()))) + } +} + diff --git a/lib/core/libimagerror/src/lib.rs b/lib/core/libimagerror/src/lib.rs index 22391142..9b5e8407 100644 --- a/lib/core/libimagerror/src/lib.rs +++ b/lib/core/libimagerror/src/lib.rs @@ -44,6 +44,7 @@ pub mod errors; pub mod exit; pub mod io; pub mod iter; +pub mod result; pub mod str; pub mod trace; diff --git a/lib/core/libimagerror/src/result.rs b/lib/core/libimagerror/src/result.rs new file mode 100644 index 00000000..0dcb5333 --- /dev/null +++ b/lib/core/libimagerror/src/result.rs @@ -0,0 +1,38 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2019 the imag 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 +// + +/// Extension trait for doing `Result, E> -> Result` +pub trait ResultOptionExt + where T: Sized, + E: Sized, + F: FnOnce() -> E +{ + fn inner_ok_or_else(self, f: F) -> Result; +} + +impl ResultOptionExt for Result, E> + where T: Sized, + E: Sized, + F: FnOnce() -> E +{ + fn inner_ok_or_else(self, f: F) -> Result { + self.and_then(|opt| opt.ok_or_else(f)) + } +} +