diff options
| -rw-r--r-- | library/core/src/option.rs | 36 | ||||
| -rw-r--r-- | library/coretests/tests/lib.rs | 1 |
2 files changed, 37 insertions, 0 deletions
diff --git a/library/core/src/option.rs b/library/core/src/option.rs index e83e77344cf..fa09409b6da 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1961,6 +1961,42 @@ impl<T> Option<T> { _ => None, } } + + /// Reduces two options into one, using the provided function if both are `Some`. + /// + /// If `self` is `Some(s)` and `other` is `Some(o)`, this method returns `Some(f(s, o))`. + /// Otherwise, if only one of `self` and `other` is `Some`, that one is returned. + /// If both `self` and `other` are `None`, `None` is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(option_reduce)] + /// + /// let s12 = Some(12); + /// let s17 = Some(17); + /// let n = None; + /// let f = |a, b| a + b; + /// + /// assert_eq!(s12.reduce(s17, f), Some(29)); + /// assert_eq!(s12.reduce(n, f), Some(12)); + /// assert_eq!(n.reduce(s17, f), Some(17)); + /// assert_eq!(n.reduce(n, f), None); + /// ``` + #[unstable(feature = "option_reduce", issue = "144273")] + pub fn reduce<U, R, F>(self, other: Option<U>, f: F) -> Option<R> + where + T: Into<R>, + U: Into<R>, + F: FnOnce(T, U) -> R, + { + match (self, other) { + (Some(a), Some(b)) => Some(f(a, b)), + (Some(a), _) => Some(a.into()), + (_, Some(b)) => Some(b.into()), + _ => None, + } + } } impl<T, U> Option<(T, U)> { diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 4415b614817..b9b768f29d7 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -80,6 +80,7 @@ #![feature(next_index)] #![feature(non_exhaustive_omitted_patterns_lint)] #![feature(numfmt)] +#![feature(option_reduce)] #![feature(pattern)] #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] |
