1#[derive(Copy, Clone, PartialOrd, Eq, Ord, Debug, Hash)]
33pub struct Opt<T> {
34 empty: bool,
35 value: T,
36}
37
38impl<T> PartialEq for Opt<T>
39where
40 T: std::cmp::PartialEq,
41{
42 fn eq(&self, other: &Self) -> bool {
43 if self.empty && other.empty {
44 true
45 } else if !self.empty && !other.empty {
46 self.value == other.value
47 } else {
48 false
49 }
50 }
51}
52
53impl<T> Opt<T> {
54 pub fn none(value: T) -> Opt<T> {
59 Opt { empty: true, value }
60 }
61
62 pub fn some(value: T) -> Opt<T> {
64 Opt {
65 empty: false,
66 value,
67 }
68 }
69}
70
71impl<T> Opt<T> {
72 pub fn is_none(&self) -> bool {
75 self.empty
76 }
77
78 pub fn is_some(&self) -> bool {
79 !self.empty
80 }
81
82 pub fn set_none(&mut self) {
85 self.empty = true;
86 }
87
88 pub fn set_some(&mut self) {
89 self.empty = false;
90 }
91
92 pub fn set_some_value(&mut self, value: T) {
93 self.empty = false;
94 self.value = value;
95 }
96
97 pub fn as_ref(&self) -> Opt<&T> {
101 Opt {
102 empty: self.empty,
103 value: &self.value,
104 }
105 }
106
107 pub fn as_mut(&mut self) -> Opt<&mut T> {
109 Opt {
110 empty: self.empty,
111 value: &mut self.value,
112 }
113 }
114
115 pub fn expect(self, msg: &str) -> T {
124 if !self.empty {
125 self.value
126 } else {
127 panic!("{}", msg);
128 }
129 }
130
131 pub fn unwrap(self) -> T {
132 if !self.empty {
133 self.value
134 } else {
135 panic!("called `unwrap()` on an empty value")
136 }
137 }
138
139 pub fn unwrap_or(self, default: T) -> T {
140 if !self.empty {
141 self.value
142 } else {
143 default
144 }
145 }
146
147 pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
148 if !self.empty {
149 self.value
150 } else {
151 f()
152 }
153 }
154
155 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {
161 Opt {
162 empty: self.empty,
163 value: f(self.value),
164 }
165 }
166
167 pub fn map_in_place<F: FnOnce(&mut T)>(&mut self, f: F) {
168 f(&mut self.value);
169 }
170
171 pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
172 if !self.empty {
173 f(self.value)
174 } else {
175 default
176 }
177 }
178
179 pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
180 if !self.empty {
181 f(self.value)
182 } else {
183 default()
184 }
185 }
186
187 pub fn ok_or<E>(self, err: E) -> Result<T, E> {
188 if !self.empty {
189 Ok(self.value)
190 } else {
191 Err(err)
192 }
193 }
194
195 pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
196 if !self.empty {
197 Ok(self.value)
198 } else {
199 Err(err())
200 }
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207
208 #[test]
211 fn test_eq_none() {
212 let none_1: Opt<String> = Opt::none(String::with_capacity(22));
213 let none_2: Opt<String> = Opt::none(String::with_capacity(44));
214 assert_eq!(none_1, none_2);
215 }
216
217 #[test]
218 fn test_eq_some() {
219 let some_thing_1: Opt<String> = Opt::some(String::from("thing"));
220 let some_thing_2: Opt<String> = Opt::some(String::from("thing"));
221 assert_eq!(some_thing_1, some_thing_2);
222 }
223
224 #[test]
225 fn test_ne_some() {
226 let some_day: Opt<String> = Opt::some(String::from("day"));
227 let some_where: Opt<String> = Opt::some(String::from("where"));
228 assert_ne!(some_day, some_where);
229 }
230
231 #[test]
232 fn test_ne_some_none() {
233 let some: Opt<String> = Opt::some(String::from("future"));
234 let none: Opt<String> = Opt::none(String::with_capacity(22));
235 assert_ne!(some, none);
236 }
237
238 #[test]
241 fn test_is_some_some() {
242 let opt: Opt<i16> = Opt::some(42);
243 assert_eq!(opt.is_none(), false);
244 assert_eq!(opt.is_some(), true);
245 }
246
247 #[test]
248 fn test_is_none_none() {
249 let opt: Opt<i16> = Opt::none(13);
250 assert_eq!(opt.is_none(), true);
251 assert_eq!(opt.is_some(), false);
252 }
253
254 #[test]
257 fn test_set_none_1() {
258 let mut opt: Opt<i16> = Opt::none(13);
259 opt.set_none();
260 assert_eq!(opt.is_none(), true);
261 assert_eq!(opt.is_some(), false);
262 }
263
264 #[test]
265 fn test_set_none_2() {
266 let mut opt: Opt<i16> = Opt::some(42);
267 opt.set_none();
268 assert_eq!(opt.is_none(), true);
269 assert_eq!(opt.is_some(), false);
270 }
271
272 #[test]
273 fn test_set_some_1() {
274 let mut opt: Opt<i16> = Opt::none(13);
275 opt.set_some();
276 assert_eq!(opt.is_none(), false);
277 assert_eq!(opt.is_some(), true);
278 assert_eq!(opt.unwrap(), 13);
279 }
280
281 #[test]
282 fn test_set_some_2() {
283 let mut opt: Opt<i16> = Opt::some(13);
284 opt.set_some();
285 assert_eq!(opt.is_none(), false);
286 assert_eq!(opt.is_some(), true);
287 assert_eq!(opt.unwrap(), 13);
288 }
289
290 #[test]
291 fn test_set_some_value_1() {
292 let mut opt: Opt<i16> = Opt::none(13);
293 opt.set_some_value(7);
294 assert_eq!(opt.is_none(), false);
295 assert_eq!(opt.is_some(), true);
296 assert_eq!(opt.unwrap(), 7);
297 }
298
299 #[test]
300 fn test_set_some_value_2() {
301 let mut opt: Opt<i16> = Opt::some(13);
302 opt.set_some_value(7);
303 assert_eq!(opt.is_none(), false);
304 assert_eq!(opt.is_some(), true);
305 assert_eq!(opt.unwrap(), 7);
306 }
307
308 #[test]
311 fn test_as_ref_some() {
312 let opt: Opt<i16> = Opt::some(42);
313 assert_eq!(opt.as_ref(), Opt::some(&42));
314 }
315
316 #[test]
317 fn test_as_ref_none() {
318 let opt: Opt<i16> = Opt::none(53);
319 assert_eq!(opt.as_ref(), Opt::none(&7));
320 }
321
322 #[test]
325 fn test_as_mut_some() {
326 let mut opt: Opt<i16> = Opt::some(42);
327 assert_eq!(opt.as_mut(), Opt::some(&mut 42));
328 }
329
330 #[test]
331 fn test_as_mut_none() {
332 let mut opt: Opt<i16> = Opt::none(53);
333 assert_eq!(opt.as_mut(), Opt::none(&mut 7));
334 }
335
336 #[test]
339 fn test_expect_some() {
340 assert_eq!(Opt::some(42).expect("error"), 42);
341 }
342
343 #[test]
344 #[should_panic(expected = "Douglas Adams")]
345 fn test_expect_none() {
346 Opt::none(29).expect("Douglas Adams");
347 }
348
349 #[test]
352 fn test_unwrap_some() {
353 assert_eq!(Opt::some(42).unwrap(), 42);
354 }
355
356 #[test]
357 #[should_panic]
358 fn test_unwrap_none() {
359 Opt::none(31).unwrap();
360 }
361
362 #[test]
365 fn test_unwrap_or_some() {
366 assert_eq!(Opt::some(42).unwrap_or(99), 42);
367 }
368
369 #[test]
370 fn test_unwrap_or_none() {
371 assert_eq!(Opt::none(-97).unwrap_or(99), 99);
372 }
373
374 #[test]
377 fn test_unwrap_or_else_some() {
378 assert_eq!(Opt::some(42).unwrap_or_else(|| -1), 42);
379 }
380
381 #[test]
382 fn test_unwrap_or_else_none() {
383 assert_eq!(Opt::none(-37).unwrap_or_else(|| -1), -1);
384 }
385
386 #[test]
389 fn test_map_some_1() {
390 assert_eq!(Opt::some(42).map(|x| x + 1), Opt::some(43));
391 }
392
393 #[test]
394 fn test_map_some_2() {
395 let opt_1: Opt<String> = Opt::some(String::from("A"));
396 let opt_2 = opt_1.map(|mut s| {
397 s.push_str("B");
398 s
399 });
400 assert_eq!(opt_2, Opt::some(String::from("AB")));
401 }
402
403 #[test]
404 fn test_map_none_1() {
405 assert_eq!(Opt::none(431).map(|x| x + 1), Opt::none(0));
406 }
407
408 #[test]
409 fn test_map_none_2() {
410 let opt_1: Opt<String> = Opt::none(String::from("A"));
411 let opt_2 = opt_1.map(|mut s| {
412 s.push_str("B");
413 s
414 });
415 assert_eq!(opt_2, Opt::none(String::from("AB")));
416 }
417
418 #[test]
421 fn test_map_in_place_some() {
422 let mut opt = Opt::some(String::from("A"));
423 opt.map_in_place(|s| s.push_str("B"));
424 assert_eq!(opt, Opt::some(String::from("AB")));
425 }
426
427 #[test]
428 fn test_map_in_place_none() {
429 let mut opt = Opt::none(String::from("A"));
430 opt.map_in_place(|s| s.push_str("B"));
431 assert_eq!(opt, Opt::none(String::from("AB")));
432 }
433}