Skip to main content

orx_concurrent_option/
into.rs

1use crate::{concurrent_option::ConcurrentOption, states::*};
2use core::sync::atomic::Ordering;
3
4impl<T> ConcurrentOption<T> {
5    /// Returns the contained Some value, consuming the `self` value.
6    ///
7    /// # Panics
8    ///
9    /// Panics if the value is a None with a custom panic message provided by
10    /// `message`.
11    ///
12    /// # Examples
13    ///
14    /// ```rust
15    /// use orx_concurrent_option::*;
16    ///
17    /// let x = ConcurrentOption::some("value");
18    /// assert_eq!(x.expect("fruits are healthy"), "value");
19    /// ```
20    ///
21    /// ```should_panic
22    /// use orx_concurrent_option::*;
23    ///
24    /// let x: ConcurrentOption<&str> = ConcurrentOption::none();
25    /// x.expect("fruits are healthy"); // panics with `fruits are healthy`
26    /// ```
27    pub fn expect(mut self, message: &str) -> T {
28        self.exclusive_take().expect(message)
29    }
30
31    /// Returns the contained Some value, consuming the `self` value.
32    ///
33    /// Because this function may panic, its use is generally discouraged.
34    /// Instead, prefer to use pattern matching and handle the None
35    /// case explicitly, or call [`ConcurrentOption::unwrap_or`], [`ConcurrentOption::unwrap_or_else`], or
36    /// [`ConcurrentOption::unwrap_or_default`].
37    ///
38    /// # Panics
39    ///
40    /// Panics if the self value equals None.
41    ///
42    /// # Examples
43    ///
44    /// ```rust
45    /// use orx_concurrent_option::*;
46    ///
47    /// let x = ConcurrentOption::some("air");
48    /// assert_eq!(x.unwrap(), "air");
49    /// ```
50    ///
51    /// ```should_panic
52    /// use orx_concurrent_option::*;
53    ///
54    /// let x: ConcurrentOption<&str> = ConcurrentOption::none();
55    /// assert_eq!(x.unwrap(), "air"); // fails
56    /// ```
57    pub fn unwrap(self) -> T {
58        self.expect("called `unwrap()` on a `None` value")
59    }
60
61    /// Returns the contained Some value or a provided default.
62    ///
63    /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing
64    /// the result of a function call, it is recommended to use [`ConcurrentOption::unwrap_or_else`],
65    /// which is lazily evaluated.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use orx_concurrent_option::*;
71    ///
72    /// assert_eq!(ConcurrentOption::some("car").unwrap_or("bike"), "car");
73    /// assert_eq!(ConcurrentOption::none().unwrap_or("bike"), "bike");
74    /// ```
75    pub fn unwrap_or(mut self, default: T) -> T {
76        self.exclusive_take().unwrap_or(default)
77    }
78
79    /// Returns the contained Some value or a default.
80    ///
81    /// Consumes the `self` argument then, if Some, returns the contained
82    /// value, otherwise if None, returns the [default value] for that
83    /// type.
84    ///
85    /// # Examples
86    ///
87    /// ```
88    /// use orx_concurrent_option::*;
89    ///
90    /// let x: ConcurrentOption<u32> = ConcurrentOption::none();
91    /// let y: ConcurrentOption<u32> = ConcurrentOption::some(12);
92    ///
93    /// assert_eq!(x.unwrap_or_default(), 0);
94    /// assert_eq!(y.unwrap_or_default(), 12);
95    /// ```
96    pub fn unwrap_or_default(mut self) -> T
97    where
98        T: Default,
99    {
100        self.exclusive_take().unwrap_or_default()
101    }
102
103    /// Returns the contained Some value or computes it from a closure.
104    ///
105    /// # Examples
106    ///
107    /// ```
108    /// use orx_concurrent_option::*;
109    ///
110    /// let k = 10;
111    /// assert_eq!(ConcurrentOption::some(4).unwrap_or_else(|| 2 * k), 4);
112    /// assert_eq!(ConcurrentOption::none().unwrap_or_else(|| 2 * k), 20);
113    /// ```
114    pub fn unwrap_or_else<F>(mut self, f: F) -> T
115    where
116        F: FnOnce() -> T,
117    {
118        self.exclusive_take().unwrap_or_else(f)
119    }
120
121    /// Returns the contained Some value, consuming the `self` value,
122    /// without checking that the value is not None.
123    ///
124    /// # Safety
125    ///
126    /// Calling this method on None is *[undefined behavior]*.
127    ///
128    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
129    ///
130    /// # Examples
131    ///
132    /// ```
133    /// use orx_concurrent_option::*;
134    ///
135    /// let x = ConcurrentOption::some("air");
136    /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
137    /// ```
138    ///
139    /// ```no_run
140    /// use orx_concurrent_option::*;
141    ///
142    /// let x: ConcurrentOption<&str> = ConcurrentOption::none();
143    /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); // Undefined behavior!
144    /// ```
145    pub unsafe fn unwrap_unchecked(self) -> T {
146        self.state.store(NONE, Ordering::Relaxed);
147        let x = unsafe { &mut *self.value.get() };
148        unsafe { x.assume_init_read() }
149    }
150}