about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-08-27 11:26:48 +0200
committerGitHub <noreply@github.com>2025-08-27 11:26:48 +0200
commit1e909228646f521fcbd77a8d24b4e9f032753b76 (patch)
tree8ce09b17c0bd3817f4a3488b2009f40b4ea03384
parent4f808ba6bf9f1c8dde30d009e73386d984491587 (diff)
parent613080b5f1d58a2496d9f8dc8c314d5432fe3d6f (diff)
downloadrust-1e909228646f521fcbd77a8d24b4e9f032753b76.tar.gz
rust-1e909228646f521fcbd77a8d24b4e9f032753b76.zip
Rollup merge of #144274 - Qelxiros:option-reduce, r=tgross35
add Option::reduce

Tracking issue: rust-lang/rust#144273
-rw-r--r--library/core/src/option.rs36
-rw-r--r--library/coretests/tests/lib.rs1
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)]