From 5419abd4009e7e0f14c95c16de48f819563b7066 Mon Sep 17 00:00:00 2001 From: Michael Watzko Date: Mon, 31 Jul 2023 15:34:41 +0200 Subject: [PATCH] Implement Option::take_if --- library/core/src/option.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) 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 @@ pub const fn take(&mut self) -> Option { 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

(&mut self, predicate: P) -> Option + 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.