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