]> git.lizzy.rs Git - rust.git/blob - src/libstd/option.rs
f5e5dbb3dbf7ff5db30dddd4fa8d9b62799b9274
[rust.git] / src / libstd / option.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12
13 Operations on the ubiquitous `Option` type.
14
15 Type `Option` represents an optional value.
16
17 Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
18 languages you might use a nullable type, in Rust you would use an option
19 type.
20
21 Options are most commonly used with pattern matching to query the presence
22 of a value and take action, always accounting for the `None` case.
23
24 # Example
25
26 ~~~
27 let msg = Some(~"howdy");
28
29 // Take a reference to the contained string
30 match msg {
31     Some(ref m) => io::println(m),
32     None => ()
33 }
34
35 // Remove the contained string, destroying the Option
36 let unwrapped_msg = match msg {
37     Some(m) => m,
38     None => ~"default message"
39 };
40 ~~~
41
42 */
43
44 use clone::Clone;
45 use cmp::{Eq,Ord};
46 use ops::Add;
47 use util;
48 use num::Zero;
49 use iterator::Iterator;
50 use str::StrSlice;
51 use clone::DeepClone;
52
53 #[cfg(test)] use str;
54 #[cfg(test)] use iterator::IteratorUtil;
55
56 /// The option type
57 #[deriving(Clone, DeepClone, Eq)]
58 pub enum Option<T> {
59     None,
60     Some(T),
61 }
62
63 impl<T:Ord> Ord for Option<T> {
64     fn lt(&self, other: &Option<T>) -> bool {
65         match (self, other) {
66             (&None, &None) => false,
67             (&None, &Some(_)) => true,
68             (&Some(_), &None) => false,
69             (&Some(ref a), &Some(ref b)) => *a < *b
70         }
71     }
72
73     fn le(&self, other: &Option<T>) -> bool {
74         match (self, other) {
75             (&None, &None) => true,
76             (&None, &Some(_)) => true,
77             (&Some(_), &None) => false,
78             (&Some(ref a), &Some(ref b)) => *a <= *b
79         }
80     }
81
82     fn ge(&self, other: &Option<T>) -> bool {
83         !(self < other)
84     }
85
86     fn gt(&self, other: &Option<T>) -> bool {
87         !(self <= other)
88     }
89 }
90
91 impl<T:Clone+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
92     #[inline]
93     fn add(&self, other: &Option<T>) -> Option<T> {
94         match (&*self, &*other) {
95             (&None, &None) => None,
96             (_, &None) => (*self).clone(),
97             (&None, _) => (*other).clone(),
98             (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
99         }
100     }
101 }
102
103 impl<T> Option<T> {
104     /// Return an iterator over the possibly contained value
105     #[inline]
106     pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
107         match *self {
108             Some(ref x) => OptionIterator{opt: Some(x)},
109             None => OptionIterator{opt: None}
110         }
111     }
112
113     /// Return a mutable iterator over the possibly contained value
114     #[inline]
115     pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
116         match *self {
117             Some(ref mut x) => OptionMutIterator{opt: Some(x)},
118             None => OptionMutIterator{opt: None}
119         }
120     }
121
122     /// Returns true if the option equals `none`
123     #[inline]
124     pub fn is_none(&self) -> bool {
125         match *self { None => true, Some(_) => false }
126     }
127
128     /// Returns true if the option contains some value
129     #[inline]
130     pub fn is_some(&self) -> bool { !self.is_none() }
131
132     /// Update an optional value by optionally running its content through a
133     /// function that returns an option.
134     #[inline]
135     pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
136         match self {
137             Some(t) => f(t),
138             None => None
139         }
140     }
141
142     /// Returns the leftmost Some() value, or None if both are None.
143     #[inline]
144     pub fn or(self, optb: Option<T>) -> Option<T> {
145         match self {
146             Some(opta) => Some(opta),
147             _ => optb
148         }
149     }
150
151     /// Update an optional value by optionally running its content by reference
152     /// through a function that returns an option.
153     #[inline]
154     pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
155                             -> Option<U> {
156         match *self {
157             Some(ref x) => f(x),
158             None => None
159         }
160     }
161
162     /// Filters an optional value using given function.
163     #[inline(always)]
164     pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option<T> {
165         match self {
166             Some(x) => if(f(&x)) {Some(x)} else {None},
167             None => None
168         }
169     }
170
171     /// Maps a `some` value from one type to another by reference
172     #[inline]
173     pub fn map<'a, U>(&'a self, f: &fn(&'a T) -> U) -> Option<U> {
174         match *self { Some(ref x) => Some(f(x)), None => None }
175     }
176
177     /// Maps a `some` value from one type to another by a mutable reference
178     #[inline]
179     pub fn map_mut<'a, U>(&'a mut self, f: &fn(&'a mut T) -> U) -> Option<U> {
180         match *self { Some(ref mut x) => Some(f(x)), None => None }
181     }
182
183     /// Maps a `some` value from one type to another by a mutable reference,
184     /// or returns a default value.
185     #[inline]
186     pub fn map_mut_default<'a, U>(&'a mut self, def: U, f: &fn(&'a mut T) -> U) -> U {
187         match *self { Some(ref mut x) => f(x), None => def }
188     }
189
190     /// As `map`, but consumes the option and gives `f` ownership to avoid
191     /// copying.
192     #[inline]
193     pub fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
194         match self { None => None, Some(v) => Some(f(v)) }
195     }
196
197     /// Applies a function to the contained value or returns a default
198     #[inline]
199     pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
200         match *self { None => def, Some(ref t) => f(t) }
201     }
202
203     /// As `map_default`, but consumes the option and gives `f`
204     /// ownership to avoid copying.
205     #[inline]
206     pub fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
207         match self { None => def, Some(v) => f(v) }
208     }
209
210     /// Take the value out of the option, leaving a `None` in its place.
211     #[inline]
212     pub fn take(&mut self) -> Option<T> {
213         util::replace(self, None)
214     }
215
216     /// As `map_consume`, but swaps a None into the original option rather
217     /// than consuming it by-value.
218     #[inline]
219     pub fn take_map<U>(&mut self, blk: &fn(T) -> U) -> Option<U> {
220         self.take().map_consume(blk)
221     }
222
223     /// As `map_consume_default`, but swaps a None into the original option
224     /// rather than consuming it by-value.
225     #[inline]
226     pub fn take_map_default<U> (&mut self, def: U, blk: &fn(T) -> U) -> U {
227         self.take().map_consume_default(def, blk)
228     }
229
230     /// Apply a function to the contained value or do nothing
231     pub fn mutate(&mut self, f: &fn(T) -> T) {
232         if self.is_some() {
233             *self = Some(f(self.take_unwrap()));
234         }
235     }
236
237     /// Apply a function to the contained value or set it to a default
238     pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
239         if self.is_some() {
240             *self = Some(f(self.take_unwrap()));
241         } else {
242             *self = Some(def);
243         }
244     }
245
246     /**
247     Gets an immutable reference to the value inside an option.
248
249     # Failure
250
251     Fails if the value equals `None`
252
253     # Safety note
254
255     In general, because this function may fail, its use is discouraged
256     (calling `get` on `None` is akin to dereferencing a null pointer).
257     Instead, prefer to use pattern matching and handle the `None`
258     case explicitly.
259      */
260     #[inline]
261     pub fn get_ref<'a>(&'a self) -> &'a T {
262         match *self {
263           Some(ref x) => x,
264           None => fail!("option::get_ref none")
265         }
266     }
267
268     /**
269     Gets a mutable reference to the value inside an option.
270
271     # Failure
272
273     Fails if the value equals `None`
274
275     # Safety note
276
277     In general, because this function may fail, its use is discouraged
278     (calling `get` on `None` is akin to dereferencing a null pointer).
279     Instead, prefer to use pattern matching and handle the `None`
280     case explicitly.
281      */
282     #[inline]
283     pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
284         match *self {
285           Some(ref mut x) => x,
286           None => fail!("option::get_mut_ref none")
287         }
288     }
289
290     #[inline]
291     pub fn unwrap(self) -> T {
292         /*!
293         Moves a value out of an option type and returns it.
294
295         Useful primarily for getting strings, vectors and unique pointers out
296         of option types without copying them.
297
298         # Failure
299
300         Fails if the value equals `None`.
301
302         # Safety note
303
304         In general, because this function may fail, its use is discouraged.
305         Instead, prefer to use pattern matching and handle the `None`
306         case explicitly.
307          */
308         match self {
309           Some(x) => x,
310           None => fail!("option::unwrap none")
311         }
312     }
313
314     /**
315      * The option dance. Moves a value out of an option type and returns it,
316      * replacing the original with `None`.
317      *
318      * # Failure
319      *
320      * Fails if the value equals `None`.
321      */
322     #[inline]
323     pub fn take_unwrap(&mut self) -> T {
324         if self.is_none() { fail!("option::take_unwrap none") }
325         self.take().unwrap()
326     }
327
328     /**
329      * Gets the value out of an option, printing a specified message on
330      * failure
331      *
332      * # Failure
333      *
334      * Fails if the value equals `none`
335      */
336     #[inline]
337     pub fn expect(self, reason: &str) -> T {
338         match self {
339           Some(val) => val,
340           None => fail!(reason.to_owned()),
341         }
342     }
343
344     /**
345     Gets the value out of an option
346
347     # Failure
348
349     Fails if the value equals `None`
350
351     # Safety note
352
353     In general, because this function may fail, its use is discouraged
354     (calling `get` on `None` is akin to dereferencing a null pointer).
355     Instead, prefer to use pattern matching and handle the `None`
356     case explicitly.
357     */
358     #[inline]
359     pub fn get(self) -> T {
360         match self {
361           Some(x) => return x,
362           None => fail!("option::get none")
363         }
364     }
365
366     /// Returns the contained value or a default
367     #[inline]
368     pub fn get_or_default(self, def: T) -> T {
369         match self { Some(x) => x, None => def }
370     }
371
372     /// Applies a function zero or more times until the result is none.
373     #[inline]
374     pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
375         let mut opt = self;
376         while opt.is_some() {
377             opt = blk(opt.unwrap());
378         }
379     }
380 }
381
382 impl<T:Zero> Option<T> {
383     /// Returns the contained value or zero (for this type)
384     #[inline]
385     pub fn get_or_zero(self) -> T {
386         match self {
387             Some(x) => x,
388             None => Zero::zero()
389         }
390     }
391 }
392
393 impl<T> Zero for Option<T> {
394     fn zero() -> Option<T> { None }
395     fn is_zero(&self) -> bool { self.is_none() }
396 }
397
398 /// Immutable iterator over an `Option<A>`
399 pub struct OptionIterator<'self, A> {
400     priv opt: Option<&'self A>
401 }
402
403 impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
404     fn next(&mut self) -> Option<&'self A> {
405         util::replace(&mut self.opt, None)
406     }
407
408     fn size_hint(&self) -> (uint, Option<uint>) {
409         match self.opt {
410             Some(_) => (1, Some(1)),
411             None => (0, Some(0)),
412         }
413     }
414 }
415
416 /// Mutable iterator over an `Option<A>`
417 pub struct OptionMutIterator<'self, A> {
418     priv opt: Option<&'self mut A>
419 }
420
421 impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
422     fn next(&mut self) -> Option<&'self mut A> {
423         util::replace(&mut self.opt, None)
424     }
425
426     fn size_hint(&self) -> (uint, Option<uint>) {
427         match self.opt {
428             Some(_) => (1, Some(1)),
429             None => (0, Some(0)),
430         }
431     }
432 }
433
434 #[test]
435 fn test_unwrap_ptr() {
436     unsafe {
437         let x = ~0;
438         let addr_x: *int = ::cast::transmute(&*x);
439         let opt = Some(x);
440         let y = opt.unwrap();
441         let addr_y: *int = ::cast::transmute(&*y);
442         assert_eq!(addr_x, addr_y);
443     }
444 }
445
446 #[test]
447 fn test_unwrap_str() {
448     let x = ~"test";
449     let addr_x = str::as_buf(x, |buf, _len| buf);
450     let opt = Some(x);
451     let y = opt.unwrap();
452     let addr_y = str::as_buf(y, |buf, _len| buf);
453     assert_eq!(addr_x, addr_y);
454 }
455
456 #[test]
457 fn test_unwrap_resource() {
458     struct R {
459        i: @mut int,
460     }
461
462     #[unsafe_destructor]
463     impl ::ops::Drop for R {
464        fn drop(&self) { *(self.i) += 1; }
465     }
466
467     fn R(i: @mut int) -> R {
468         R {
469             i: i
470         }
471     }
472
473     let i = @mut 0;
474     {
475         let x = R(i);
476         let opt = Some(x);
477         let _y = opt.unwrap();
478     }
479     assert_eq!(*i, 1);
480 }
481
482 #[test]
483 fn test_option_dance() {
484     let x = Some(());
485     let mut y = Some(5);
486     let mut y2 = 0;
487     for x.iter().advance |_x| {
488         y2 = y.take_unwrap();
489     }
490     assert_eq!(y2, 5);
491     assert!(y.is_none());
492 }
493 #[test] #[should_fail] #[ignore(cfg(windows))]
494 fn test_option_too_much_dance() {
495     let mut y = Some(util::NonCopyable);
496     let _y2 = y.take_unwrap();
497     let _y3 = y.take_unwrap();
498 }
499
500 #[test]
501 fn test_option_while_some() {
502     let mut i = 0;
503     do Some(10).while_some |j| {
504         i += 1;
505         if (j > 0) {
506             Some(j-1)
507         } else {
508             None
509         }
510     }
511     assert_eq!(i, 11);
512 }
513
514 #[test]
515 fn test_get_or_zero() {
516     let some_stuff = Some(42);
517     assert_eq!(some_stuff.get_or_zero(), 42);
518     let no_stuff: Option<int> = None;
519     assert_eq!(no_stuff.get_or_zero(), 0);
520 }
521
522 #[test]
523 fn test_filtered() {
524     let some_stuff = Some(42);
525     let modified_stuff = some_stuff.filtered(|&x| {x < 10});
526     assert_eq!(some_stuff.get(), 42);
527     assert!(modified_stuff.is_none());
528 }
529
530 #[test]
531 fn test_iter() {
532     let val = 5;
533
534     let x = Some(val);
535     let mut it = x.iter();
536
537     assert_eq!(it.size_hint(), (1, Some(1)));
538     assert_eq!(it.next(), Some(&val));
539     assert_eq!(it.size_hint(), (0, Some(0)));
540     assert!(it.next().is_none());
541 }
542
543 #[test]
544 fn test_mut_iter() {
545     let val = 5;
546     let new_val = 11;
547
548     let mut x = Some(val);
549     let mut it = x.mut_iter();
550
551     assert_eq!(it.size_hint(), (1, Some(1)));
552
553     match it.next() {
554         Some(interior) => {
555             assert_eq!(*interior, val);
556             *interior = new_val;
557             assert_eq!(x, Some(new_val));
558         }
559         None => assert!(false),
560     }
561
562     assert_eq!(it.size_hint(), (0, Some(0)));
563     assert!(it.next().is_none());
564 }