about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Watzko <michael@watzko.de>2023-07-31 15:34:41 +0200
committerMichael Watzko <michael.watzko@it-designers.de>2023-08-03 09:34:18 +0200
commit5419abd4009e7e0f14c95c16de48f819563b7066 (patch)
tree1dd0846985ae030d60291494a55b735cb2daf2d6
parent601a34de8c10458b72a7781eb0b44a7981e4a2b1 (diff)
downloadrust-5419abd4009e7e0f14c95c16de48f819563b7066.tar.gz
rust-5419abd4009e7e0f14c95c16de48f819563b7066.zip
Implement Option::take_if
-rw-r--r--library/core/src/option.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 9b6ff76b240..264a53f43dc 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -1697,6 +1697,41 @@ impl<T> Option<T> {
         mem::replace(self, None)
     }
 
+    /// Takes the value out of the option, but only if the predicate evaluates to
+    /// `true` on a mutable reference to the value.
+    ///
+    /// In other words, replaces `self` with `None` if the predicate returns `true`.
+    /// This method operates similar to [`Option::take`] but conditional.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(option_take_if)]
+    ///
+    /// let mut x = Some(42);
+    ///
+    /// let prev = x.take_if(|v| if *v == 42 {
+    ///     *v += 1;
+    ///     false
+    /// } else {
+    ///     false
+    /// });
+    /// assert_eq!(x, Some(43));
+    /// assert_eq!(prev, None);
+    ///
+    /// let prev = x.take_if(|v| *v == 43);
+    /// assert_eq!(x, None);
+    /// assert_eq!(prev, Some(43));
+    /// ```
+    #[inline]
+    #[unstable(feature = "option_take_if", issue = "98934")]
+    pub fn take_if<P>(&mut self, predicate: P) -> Option<T>
+    where
+        P: FnOnce(&mut T) -> bool,
+    {
+        if self.as_mut().map_or(false, predicate) { self.take() } else { None }
+    }
+
     /// Replaces the actual value in the option by the value given in parameter,
     /// returning the old value if present,
     /// leaving a [`Some`] in its place without deinitializing either one.