possible/
replace.rs

1use super::Possible;
2use core::{hint, mem};
3
4impl<T> Possible<T> {
5    /// Takes the value out of the option, leaving a [`Possible::Void`] in its place.
6    ///
7    /// # Examples
8    ///
9    /// ```
10    /// use possible::Possible;
11    ///
12    /// let mut x = Possible::Some(2);
13    /// let y = x.take();
14    /// assert_eq!(x, Possible::Void);
15    /// assert_eq!(y, Possible::Some(2));
16    ///
17    /// let mut x: Possible<u32> = Possible::None;
18    /// let y = x.take();
19    /// assert_eq!(x, Possible::Void);
20    /// assert_eq!(y, Possible::None);
21    /// ```
22    #[inline]
23    pub fn take(&mut self) -> Possible<T> {
24        mem::take(self)
25    }
26
27    /// Inserts `value` into the `Possible` then returns a mutable reference to it.
28    ///
29    /// If the `Possible` already contains a value, the old value is dropped.
30    ///
31    /// See also [`Possible::get_or_insert`], which doesn't update the value if
32    /// the option already contains [`Possible::Some`].
33    ///
34    /// # Example
35    ///
36    /// ```
37    /// use possible::Possible;
38    ///
39    /// let mut opt = Possible::None;
40    /// let val = opt.insert(1);
41    /// assert_eq!(*val, 1);
42    /// assert_eq!(opt.unwrap(), 1);
43    /// let val = opt.insert(2);
44    /// assert_eq!(*val, 2);
45    /// *val = 3;
46    /// assert_eq!(opt.unwrap(), 3);
47    /// ```
48    #[must_use = "if you intended to set a value, consider assignment instead"]
49    #[inline]
50    pub fn insert(&mut self, value: T) -> &mut T {
51        *self = Possible::Some(value);
52
53        match self {
54            Possible::Some(v) => v,
55            // SAFETY: the code above just filled the option
56            Possible::None | Possible::Void => unsafe { hint::unreachable_unchecked() },
57        }
58    }
59
60    /// Inserts `value` into the `Possible` if it is [`Possible::None`] or
61    /// [`Possible::Void`], then returns a mutable reference to the contained value.
62    ///
63    /// See also [`Possible::insert`], which updates the value even if
64    /// the `Possible` already contains [`Some`].
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use possible::Possible;
70    ///
71    /// let mut x = Possible::None;
72    ///
73    /// {
74    ///     let y: &mut u32 = x.get_or_insert(5);
75    ///     assert_eq!(y, &5);
76    ///
77    ///     *y = 7;
78    /// }
79    ///
80    /// assert_eq!(x, Possible::Some(7));
81    /// ```
82    ///
83    /// ```
84    /// use possible::Possible;
85    ///
86    /// let mut x = Possible::Void;
87    ///
88    /// {
89    ///     let y: &mut u32 = x.get_or_insert(3);
90    ///     assert_eq!(y, &3);
91    ///
92    ///     *y = 4;
93    /// }
94    ///
95    /// assert_eq!(x, Possible::Some(4));
96    /// ```
97    #[inline]
98    pub fn get_or_insert(&mut self, value: T) -> &mut T {
99        self.get_or_insert_with(|| value)
100    }
101
102    /// Inserts the default value into the option if it is [`Possible::None`] or
103    /// or [`Possible::Void`], then returns a mutable reference to the contained value.
104    ///
105    /// # Examples
106    ///
107    /// ```
108    /// use possible::Possible;
109    ///
110    /// let mut x = Possible::None;
111    ///
112    /// {
113    ///     let y: &mut u32 = x.get_or_insert_default();
114    ///     assert_eq!(y, &0);
115    ///
116    ///     *y = 7;
117    /// }
118    ///
119    /// assert_eq!(x, Possible::Some(7));
120    /// ```
121    ///
122    /// ```
123    /// use possible::Possible;
124    ///
125    /// let mut x = Possible::Void;
126    ///
127    /// {
128    ///     let y: &mut u32 = x.get_or_insert_default();
129    ///     assert_eq!(y, &0);
130    ///
131    ///     *y = 4;
132    /// }
133    ///
134    /// assert_eq!(x, Possible::Some(4));
135    /// ```
136    #[inline]
137    pub fn get_or_insert_default(&mut self) -> &mut T
138    where
139        T: Default,
140    {
141        self.get_or_insert_with(Default::default)
142    }
143
144    /// Inserts a value computed from `f` into the `Possible` if it is [`Possible::None`]
145    /// or [`Possible::Void`] then returns a mutable reference to the contained value.
146    ///
147    /// # Examples
148    ///
149    /// ```
150    /// use possible::Possible;
151    ///
152    /// let mut x = Possible::None;
153    ///
154    /// {
155    ///     let y: &mut u32 = x.get_or_insert_with(|| 5);
156    ///     assert_eq!(y, &5);
157    ///
158    ///     *y = 7;
159    /// }
160    ///
161    /// assert_eq!(x, Possible::Some(7));
162    /// ```
163    ///
164    /// ```
165    /// use possible::Possible;
166    ///
167    /// let mut x = Possible::Void;
168    ///
169    /// {
170    ///     let y: &mut u32 = x.get_or_insert_with(|| 3);
171    ///     assert_eq!(y, &3);
172    ///
173    ///     *y = 4;
174    /// }
175    ///
176    /// assert_eq!(x, Possible::Some(4));
177    /// ```
178    #[inline]
179    pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
180        if let Possible::None | Possible::Void = *self {
181            *self = Possible::Some(f());
182        }
183
184        match self {
185            Possible::Some(v) => v,
186            // SAFETY: a `Possible::None` or a `Possible::Void` variant for `self`
187            // would have been replaced by a `Some` variant in the code above.
188            Possible::None | Possible::Void => unsafe { hint::unreachable_unchecked() },
189        }
190    }
191
192    /// Replaces the actual value in the option by the value given in parameter,
193    /// returning the old value if present,
194    /// leaving a [`Some`] in its place without deinitializing either one.
195    ///
196    /// # Examples
197    ///
198    /// ```
199    /// use possible::Possible;
200    ///
201    /// let mut x = Possible::Some(2);
202    /// let old = x.replace(5);
203    /// assert_eq!(x, Possible::Some(5));
204    /// assert_eq!(old, Possible::Some(2));
205    /// ```
206    ///
207    /// ```
208    /// use possible::Possible;
209    ///
210    /// let mut x = Possible::None;
211    /// let old = x.replace(3);
212    /// assert_eq!(x, Possible::Some(3));
213    /// assert_eq!(old, Possible::None);
214    /// ```
215    ///
216    /// ```
217    /// use possible::Possible;
218    ///
219    /// let mut x = Possible::Void;
220    /// let old = x.replace(7);
221    /// assert_eq!(x, Possible::Some(7));
222    /// assert_eq!(old, Possible::Void);
223    /// ```
224    #[inline]
225    pub fn replace(&mut self, value: T) -> Possible<T> {
226        mem::replace(self, Possible::Some(value))
227    }
228}