about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-07-04 05:47:22 +0200
committerGitHub <noreply@github.com>2025-07-04 05:47:22 +0200
commite080bc875112a71b7f3043057c661e064eab5b69 (patch)
tree15900c946877a8931c0c7a395022575b281a9dc1
parent837c5dd7de03aa97190593aef4e70d53e1bb574b (diff)
parent19352e9d9336b851aba2130ff6e448a481262861 (diff)
downloadrust-e080bc875112a71b7f3043057c661e064eab5b69.tar.gz
rust-e080bc875112a71b7f3043057c661e064eab5b69.zip
Rollup merge of #142749 - LimpSquid:bool_to_result, r=scottmcm
Add methods for converting bool to `Result<(), E>`

## Tracking Issue

https://github.com/rust-lang/rust/issues/142748

## ACP

https://github.com/rust-lang/libs-team/issues/606
-rw-r--r--library/core/src/bool.rs67
-rw-r--r--library/coretests/tests/bool.rs8
-rw-r--r--library/coretests/tests/lib.rs1
3 files changed, 76 insertions, 0 deletions
diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs
index 2016ece007e..99268d6182f 100644
--- a/library/core/src/bool.rs
+++ b/library/core/src/bool.rs
@@ -61,4 +61,71 @@ impl bool {
     pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
         if self { Some(f()) } else { None }
     }
+
+    /// Returns `Ok(())` if the `bool` is [`true`](../std/keyword.true.html),
+    /// or `Err(err)` otherwise.
+    ///
+    /// Arguments passed to `ok_or` are eagerly evaluated; if you are
+    /// passing the result of a function call, it is recommended to use
+    /// [`ok_or_else`], which is lazily evaluated.
+    ///
+    /// [`ok_or_else`]: bool::ok_or_else
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(bool_to_result)]
+    ///
+    /// assert_eq!(false.ok_or(0), Err(0));
+    /// assert_eq!(true.ok_or(0), Ok(()));
+    /// ```
+    ///
+    /// ```
+    /// #![feature(bool_to_result)]
+    ///
+    /// let mut a = 0;
+    /// let mut function_with_side_effects = || { a += 1; };
+    ///
+    /// assert!(true.ok_or(function_with_side_effects()).is_ok());
+    /// assert!(false.ok_or(function_with_side_effects()).is_err());
+    ///
+    /// // `a` is incremented twice because the value passed to `ok_or` is
+    /// // evaluated eagerly.
+    /// assert_eq!(a, 2);
+    /// ```
+    #[unstable(feature = "bool_to_result", issue = "142748")]
+    #[inline]
+    pub fn ok_or<E>(self, err: E) -> Result<(), E> {
+        if self { Ok(()) } else { Err(err) }
+    }
+
+    /// Returns `Ok(())` if the `bool` is [`true`](../std/keyword.true.html),
+    /// or `Err(f())` otherwise.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(bool_to_result)]
+    ///
+    /// assert_eq!(false.ok_or_else(|| 0), Err(0));
+    /// assert_eq!(true.ok_or_else(|| 0), Ok(()));
+    /// ```
+    ///
+    /// ```
+    /// #![feature(bool_to_result)]
+    ///
+    /// let mut a = 0;
+    ///
+    /// assert!(true.ok_or_else(|| { a += 1; }).is_ok());
+    /// assert!(false.ok_or_else(|| { a += 1; }).is_err());
+    ///
+    /// // `a` is incremented once because the closure is evaluated lazily by
+    /// // `ok_or_else`.
+    /// assert_eq!(a, 1);
+    /// ```
+    #[unstable(feature = "bool_to_result", issue = "142748")]
+    #[inline]
+    pub fn ok_or_else<E, F: FnOnce() -> E>(self, f: F) -> Result<(), E> {
+        if self { Ok(()) } else { Err(f()) }
+    }
 }
diff --git a/library/coretests/tests/bool.rs b/library/coretests/tests/bool.rs
index bcd6dc2abac..eb5f0f50663 100644
--- a/library/coretests/tests/bool.rs
+++ b/library/coretests/tests/bool.rs
@@ -105,3 +105,11 @@ fn test_bool_to_option() {
     assert_eq!(D, Some(0));
     */
 }
+
+#[test]
+fn test_bool_to_result() {
+    assert_eq!(false.ok_or(0), Err(0));
+    assert_eq!(true.ok_or(0), Ok(()));
+    assert_eq!(false.ok_or_else(|| 0), Err(0));
+    assert_eq!(true.ok_or_else(|| 0), Ok(()));
+}
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 0c54609260f..fdef736c0c0 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -11,6 +11,7 @@
 #![feature(async_iter_from_iter)]
 #![feature(async_iterator)]
 #![feature(bigint_helper_methods)]
+#![feature(bool_to_result)]
 #![feature(bstr)]
 #![feature(cfg_target_has_reliable_f16_f128)]
 #![feature(char_max_len)]