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}