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}