]> git.lizzy.rs Git - rust.git/blob - src/libstd/result.rs
Find the cratemap at runtime on windows.
[rust.git] / src / libstd / result.rs
1 // Copyright 2012 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 //! A type representing either success or failure
12
13 #[allow(missing_doc)];
14
15 use clone::Clone;
16 use cmp::Eq;
17 use either;
18 use iter::Iterator;
19 use option::{None, Option, Some, OptionIterator};
20 use option;
21 use vec;
22 use vec::OwnedVector;
23 use to_str::ToStr;
24 use str::StrSlice;
25
26 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
27 ///
28 /// In order to provide informative error messages, `E` is required to implement `ToStr`.
29 /// It is further recommended for `E` to be a descriptive error type, eg a `enum` for
30 /// all possible errors cases.
31 #[deriving(Clone, Eq)]
32 pub enum Result<T, E> {
33     /// Contains the successful result value
34     Ok(T),
35     /// Contains the error value
36     Err(E)
37 }
38
39 impl<T, E: ToStr> Result<T, E> {
40     /// Get a reference to the value out of a successful result
41     ///
42     /// # Failure
43     ///
44     /// If the result is an error
45     #[inline]
46     pub fn get_ref<'a>(&'a self) -> &'a T {
47         match *self {
48             Ok(ref t) => t,
49             Err(ref e) => fail!("called `Result::get_ref()` on `Err` value: %s", e.to_str()),
50         }
51     }
52
53     /// Returns true if the result is `Ok`
54     #[inline]
55     pub fn is_ok(&self) -> bool {
56         match *self {
57             Ok(_) => true,
58             Err(_) => false
59         }
60     }
61
62     /// Returns true if the result is `Err`
63     #[inline]
64     pub fn is_err(&self) -> bool {
65         !self.is_ok()
66     }
67
68     /// Call a method based on a previous result
69     ///
70     /// If `self` is `Ok` then the value is extracted and passed to `op`
71     /// whereupon `op`s result is returned. if `self` is `Err` then it is
72     /// immediately returned. This function can be used to compose the results
73     /// of two functions.
74     ///
75     /// Example:
76     ///
77     ///     for buf in read_file(file) {
78     ///         print_buf(buf)
79     ///     }
80     #[inline]
81     pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
82         match *self {
83             Ok(ref t) => Some(t),
84             Err(*) => None,
85         }.move_iter()
86     }
87
88     /// Call a method based on a previous result
89     ///
90     /// If `self` is `Err` then the value is extracted and passed to `op`
91     /// whereupon `op`s result is returned. if `self` is `Ok` then it is
92     /// immediately returned.  This function can be used to pass through a
93     /// successful result while handling an error.
94     #[inline]
95     pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
96         match *self {
97             Ok(*) => None,
98             Err(ref t) => Some(t),
99         }.move_iter()
100     }
101
102     /// Unwraps a result, yielding the content of an `Ok`.
103     /// Fails if the value is a `Err` with an error message derived
104     /// from `E`'s `ToStr` implementation.
105     #[inline]
106     pub fn unwrap(self) -> T {
107         match self {
108             Ok(t) => t,
109             Err(e) => fail!("called `Result::unwrap()` on `Err` value: %s", e.to_str()),
110         }
111     }
112
113     /// Unwraps a result, yielding the content of an `Err`.
114     /// Fails if the value is a `Ok`.
115     #[inline]
116     pub fn unwrap_err(self) -> E {
117         self.expect_err("called `Result::unwrap_err()` on `Ok` value")
118     }
119
120     /// Unwraps a result, yielding the content of an `Ok`.
121     /// Fails if the value is a `Err` with a custom failure message.
122     #[inline]
123     pub fn expect(self, reason: &str) -> T {
124         match self {
125             Ok(t) => t,
126             Err(_) => fail!(reason.to_owned()),
127         }
128     }
129
130     /// Unwraps a result, yielding the content of an `Err`
131     /// Fails if the value is a `Ok` with a custom failure message.
132     #[inline]
133     pub fn expect_err(self, reason: &str) -> E {
134         match self {
135             Err(e) => e,
136             Ok(_) => fail!(reason.to_owned()),
137         }
138     }
139
140     /// Call a method based on a previous result
141     ///
142     /// If `self` is `Ok` then the value is extracted and passed to `op`
143     /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
144     /// `Err` then it is immediately returned.  This function can be used to
145     /// compose the results of two functions.
146     ///
147     /// Example:
148     ///
149     ///     let res = do read_file(file).map_move |buf| {
150     ///         parse_bytes(buf)
151     ///     }
152     #[inline]
153     pub fn map_move<U>(self, op: &fn(T) -> U) -> Result<U,E> {
154         match self {
155           Ok(t) => Ok(op(t)),
156           Err(e) => Err(e)
157         }
158     }
159
160     /// Call a method based on a previous result
161     ///
162     /// If `self` is `Err` then the value is extracted and passed to `op`
163     /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
164     /// `Ok` then it is immediately returned.  This function can be used to pass
165     /// through a successful result while handling an error.
166     #[inline]
167     pub fn map_err_move<F>(self, op: &fn(E) -> F) -> Result<T,F> {
168         match self {
169           Ok(t) => Ok(t),
170           Err(e) => Err(op(e))
171         }
172     }
173
174     /// Call a method based on a previous result
175     ///
176     /// If `self` is `Ok`, then `res` it is returned. If `self` is `Err`,
177     /// then `self` is returned.
178     #[inline]
179     pub fn and(self, res: Result<T, E>) -> Result<T, E> {
180         match self {
181             Ok(_) => res,
182             Err(_) => self,
183         }
184     }
185
186     /// Call a method based on a previous result
187     ///
188     /// If `self` is `Ok` then the value is extracted and passed to `op`
189     /// whereupon `op`s result is returned. If `self` is `Err` then it is
190     /// immediately returned. This function can be used to compose the results
191     /// of two functions.
192     ///
193     /// Example:
194     ///
195     ///     let res = do read_file(file) |buf| {
196     ///         Ok(parse_bytes(buf))
197     ///     };
198     #[inline]
199     pub fn and_then<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
200         match self {
201             Ok(t) => op(t),
202             Err(e) => Err(e),
203         }
204     }
205
206     /// Call a method based on a previous result
207     ///
208     /// If `self` is `Ok`, then `self` is returned. If `self` is `Err`
209     /// then `res` is returned.
210     #[inline]
211     pub fn or(self, res: Result<T, E>) -> Result<T, E> {
212         match self {
213             Ok(_) => self,
214             Err(_) => res,
215         }
216     }
217
218     /// Call a function based on a previous result
219     ///
220     /// If `self` is `Err` then the value is extracted and passed to `op`
221     /// whereupon `op`s result is returned. if `self` is `Ok` then it is
222     /// immediately returned.  This function can be used to pass through a
223     /// successful result while handling an error.
224     #[inline]
225     pub fn or_else<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
226         match self {
227             Ok(t) => Ok(t),
228             Err(e) => op(e),
229         }
230     }
231 }
232
233 impl<T: Clone, E: ToStr> Result<T, E> {
234     /// Call a method based on a previous result
235     ///
236     /// If `self` is `Err` then the value is extracted and passed to `op`
237     /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
238     /// `Ok` then it is immediately returned.  This function can be used to pass
239     /// through a successful result while handling an error.
240     #[inline]
241     pub fn map_err<F: Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
242         match *self {
243             Ok(ref t) => Ok(t.clone()),
244             Err(ref e) => Err(op(e))
245         }
246     }
247 }
248
249 impl<T, E: Clone + ToStr> Result<T, E> {
250     /// Call a method based on a previous result
251     ///
252     /// If `self` is `Ok` then the value is extracted and passed to `op`
253     /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
254     /// `Err` then it is immediately returned.  This function can be used to
255     /// compose the results of two functions.
256     ///
257     /// Example:
258     ///
259     ///     let res = do read_file(file).map |buf| {
260     ///         parse_bytes(buf)
261     ///     };
262     #[inline]
263     pub fn map<U>(&self, op: &fn(&T) -> U) -> Result<U,E> {
264         match *self {
265             Ok(ref t) => Ok(op(t)),
266             Err(ref e) => Err(e.clone())
267         }
268     }
269 }
270
271 /// A generic trait for converting a value to a `Result`
272 pub trait ToResult<T, E> {
273     /// Convert to the `result` type
274     fn to_result(&self) -> Result<T, E>;
275 }
276
277 /// A generic trait for converting a value to a `Result`
278 pub trait IntoResult<T, E> {
279     /// Convert to the `result` type
280     fn into_result(self) -> Result<T, E>;
281 }
282
283 /// A generic trait for converting a value to a `Result`
284 pub trait AsResult<T, E> {
285     /// Convert to the `result` type
286     fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>;
287 }
288
289 impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
290     #[inline]
291     fn to_option(&self)-> Option<T> {
292         match *self {
293             Ok(ref t) => Some(t.clone()),
294             Err(_) => None,
295         }
296     }
297 }
298
299 impl<T, E> option::IntoOption<T> for Result<T, E> {
300     #[inline]
301     fn into_option(self)-> Option<T> {
302         match self {
303             Ok(t) => Some(t),
304             Err(_) => None,
305         }
306     }
307 }
308
309 impl<T, E> option::AsOption<T> for Result<T, E> {
310     #[inline]
311     fn as_option<'a>(&'a self)-> Option<&'a T> {
312         match *self {
313             Ok(ref t) => Some(t),
314             Err(_) => None,
315         }
316     }
317 }
318
319 impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
320     #[inline]
321     fn to_result(&self) -> Result<T, E> { self.clone() }
322 }
323
324 impl<T, E> IntoResult<T, E> for Result<T, E> {
325     #[inline]
326     fn into_result(self) -> Result<T, E> { self }
327 }
328
329 impl<T, E> AsResult<T, E> for Result<T, E> {
330     #[inline]
331     fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
332         match *self {
333             Ok(ref t) => Ok(t),
334             Err(ref e) => Err(e),
335         }
336     }
337 }
338
339 impl<T: Clone, E: Clone> either::ToEither<E, T> for Result<T, E> {
340     #[inline]
341     fn to_either(&self)-> either::Either<E, T> {
342         match *self {
343             Ok(ref t) => either::Right(t.clone()),
344             Err(ref e) => either::Left(e.clone()),
345         }
346     }
347 }
348
349 impl<T, E> either::IntoEither<E, T> for Result<T, E> {
350     #[inline]
351     fn into_either(self)-> either::Either<E, T> {
352         match self {
353             Ok(t) => either::Right(t),
354             Err(e) => either::Left(e),
355         }
356     }
357 }
358
359 impl<T, E> either::AsEither<E, T> for Result<T, E> {
360     #[inline]
361     fn as_either<'a>(&'a self)-> either::Either<&'a E, &'a T> {
362         match *self {
363             Ok(ref t) => either::Right(t),
364             Err(ref e) => either::Left(e),
365         }
366     }
367 }
368
369 #[inline]
370 #[allow(missing_doc)]
371 pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
372                                op: &fn(&T) -> Result<V,U>) -> Result<Option<V>,U> {
373     match *o_t {
374         None => Ok(None),
375         Some(ref t) => match op(t) {
376             Ok(v) => Ok(Some(v)),
377             Err(e) => Err(e)
378         }
379     }
380 }
381
382 /// Takes each element in the iterator: if it is an error, no further
383 /// elements are taken, and the error is returned.
384 /// Should no error occur, a vector containing the values of each Result
385 /// is returned.
386 ///
387 /// Here is an example which increments every integer in a vector,
388 /// checking for overflow:
389 ///
390 ///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
391 ///         if x == uint::max_value { return Err("overflow"); }
392 ///         else { return Ok(x+1u); }
393 ///     }
394 ///     let v = [1u, 2, 3];
395 ///     let res = collect(v.iter().map(|&x| inc_conditionally(x)));
396 ///     assert!(res == Ok(~[2u, 3, 4]));
397 #[inline]
398 pub fn collect<T, E, Iter: Iterator<Result<T, E>>>(mut iterator: Iter)
399     -> Result<~[T], E> {
400     let (lower, _) = iterator.size_hint();
401     let mut vs: ~[T] = vec::with_capacity(lower);
402     for t in iterator {
403         match t {
404             Ok(v) => vs.push(v),
405             Err(u) => return Err(u)
406         }
407     }
408     Ok(vs)
409 }
410
411 /// Perform a fold operation over the result values from an iterator.
412 ///
413 /// If an `Err` is encountered, it is immediately returned.
414 /// Otherwise, the folded value is returned.
415 #[inline]
416 pub fn fold<T, V, E,
417             Iter: Iterator<Result<T, E>>>(
418             mut iterator: Iter,
419             mut init: V,
420             f: &fn(V, T) -> V)
421          -> Result<V, E> {
422     for t in iterator {
423         match t {
424             Ok(v) => init = f(init, v),
425             Err(u) => return Err(u)
426         }
427     }
428     Ok(init)
429 }
430
431 /// Perform a trivial fold operation over the result values
432 /// from an iterator.
433 ///
434 /// If an `Err` is encountered, it is immediately returned.
435 /// Otherwise, a simple `Ok(())` is returned.
436 #[inline]
437 pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
438              iterator: Iter)
439           -> Result<(), E> {
440     fold(iterator, (), |_, _| ())
441 }
442
443
444 #[cfg(test)]
445 mod tests {
446     use super::*;
447
448     use either::{IntoEither, ToEither, AsEither};
449     use either;
450     use iter::range;
451     use option::{IntoOption, ToOption, AsOption};
452     use option;
453     use str::OwnedStr;
454     use vec::ImmutableVector;
455
456     pub fn op1() -> Result<int, ~str> { Ok(666) }
457     pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
458
459     #[test]
460     pub fn test_and() {
461         assert_eq!(op1().and(Ok(667)).unwrap(), 667);
462         assert_eq!(op1().and(Err(~"bad")).unwrap_err(), ~"bad");
463
464         assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
465         assert_eq!(op2().and(Err(~"bad")).unwrap_err(), ~"sadface");
466     }
467
468     #[test]
469     pub fn test_and_then() {
470         assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
471         assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");
472
473         assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
474         assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
475     }
476
477     #[test]
478     pub fn test_or() {
479         assert_eq!(op1().or(Ok(667)).unwrap(), 666);
480         assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);
481
482         assert_eq!(op2().or(Ok(667)).unwrap(), 667);
483         assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
484     }
485
486     #[test]
487     pub fn test_or_else() {
488         assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
489         assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);
490
491         assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
492         assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
493     }
494
495     #[test]
496     pub fn test_impl_iter() {
497         let mut valid = false;
498         let okval = Ok::<~str, ~str>(~"a");
499         do okval.iter().next().map |_| { valid = true; };
500         assert!(valid);
501
502         let errval = Err::<~str, ~str>(~"b");
503         do errval.iter().next().map |_| { valid = false; };
504         assert!(valid);
505     }
506
507     #[test]
508     pub fn test_impl_iter_err() {
509         let mut valid = true;
510         let okval = Ok::<~str, ~str>(~"a");
511         do okval.iter_err().next().map |_| { valid = false };
512         assert!(valid);
513
514         valid = false;
515         let errval = Err::<~str, ~str>(~"b");
516         do errval.iter_err().next().map |_| { valid = true };
517         assert!(valid);
518     }
519
520     #[test]
521     pub fn test_impl_map() {
522         assert_eq!(Ok::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Ok(~"ba"));
523         assert_eq!(Err::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Err(~"a"));
524     }
525
526     #[test]
527     pub fn test_impl_map_err() {
528         assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Ok(~"a"));
529         assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Err(~"ba"));
530     }
531
532     #[test]
533     pub fn test_impl_map_move() {
534         assert_eq!(Ok::<~str, ~str>(~"a").map_move(|x| x + "b"), Ok(~"ab"));
535         assert_eq!(Err::<~str, ~str>(~"a").map_move(|x| x + "b"), Err(~"a"));
536     }
537
538     #[test]
539     pub fn test_impl_map_err_move() {
540         assert_eq!(Ok::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Ok(~"a"));
541         assert_eq!(Err::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Err(~"ab"));
542     }
543
544     #[test]
545     pub fn test_get_ref_method() {
546         let foo: Result<int, ()> = Ok(100);
547         assert_eq!(*foo.get_ref(), 100);
548     }
549
550     #[test]
551     fn test_collect() {
552         assert_eq!(collect(range(0, 0)
553                            .map(|_| Ok::<int, ()>(0))),
554                    Ok(~[]));
555         assert_eq!(collect(range(0, 3)
556                            .map(|x| Ok::<int, ()>(x))),
557                    Ok(~[0, 1, 2]));
558         assert_eq!(collect(range(0, 3)
559                            .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
560                    Err(2));
561
562         // test that it does not take more elements than it needs
563         let functions = [|| Ok(()), || Err(1), || fail!()];
564
565         assert_eq!(collect(functions.iter().map(|f| (*f)())),
566                    Err(1));
567     }
568
569     #[test]
570     fn test_fold() {
571         assert_eq!(fold_(range(0, 0)
572                         .map(|_| Ok::<(), ()>(()))),
573                    Ok(()));
574         assert_eq!(fold(range(0, 3)
575                         .map(|x| Ok::<int, ()>(x)),
576                         0, |a, b| a + b),
577                    Ok(3));
578         assert_eq!(fold_(range(0, 3)
579                         .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
580                    Err(2));
581
582         // test that it does not take more elements than it needs
583         let functions = [|| Ok(()), || Err(1), || fail!()];
584
585         assert_eq!(fold_(functions.iter()
586                         .map(|f| (*f)())),
587                    Err(1));
588     }
589
590     #[test]
591     pub fn test_to_option() {
592         let ok: Result<int, int> = Ok(100);
593         let err: Result<int, int> = Err(404);
594
595         assert_eq!(ok.to_option(), option::Some(100));
596         assert_eq!(err.to_option(), option::None);
597     }
598
599     #[test]
600     pub fn test_into_option() {
601         let ok: Result<int, int> = Ok(100);
602         let err: Result<int, int> = Err(404);
603
604         assert_eq!(ok.into_option(), option::Some(100));
605         assert_eq!(err.into_option(), option::None);
606     }
607
608     #[test]
609     pub fn test_as_option() {
610         let ok: Result<int, int> = Ok(100);
611         let err: Result<int, int> = Err(404);
612
613         assert_eq!(ok.as_option().unwrap(), &100);
614         assert_eq!(err.as_option(), option::None);
615     }
616
617     #[test]
618     pub fn test_to_result() {
619         let ok: Result<int, int> = Ok(100);
620         let err: Result<int, int> = Err(404);
621
622         assert_eq!(ok.to_result(), Ok(100));
623         assert_eq!(err.to_result(), Err(404));
624     }
625
626     #[test]
627     pub fn test_into_result() {
628         let ok: Result<int, int> = Ok(100);
629         let err: Result<int, int> = Err(404);
630
631         assert_eq!(ok.into_result(), Ok(100));
632         assert_eq!(err.into_result(), Err(404));
633     }
634
635     #[test]
636     pub fn test_as_result() {
637         let ok: Result<int, int> = Ok(100);
638         let err: Result<int, int> = Err(404);
639
640         let x = 100;
641         assert_eq!(ok.as_result(), Ok(&x));
642
643         let x = 404;
644         assert_eq!(err.as_result(), Err(&x));
645     }
646
647     #[test]
648     pub fn test_to_either() {
649         let ok: Result<int, int> = Ok(100);
650         let err: Result<int, int> = Err(404);
651
652         assert_eq!(ok.to_either(), either::Right(100));
653         assert_eq!(err.to_either(), either::Left(404));
654     }
655
656     #[test]
657     pub fn test_into_either() {
658         let ok: Result<int, int> = Ok(100);
659         let err: Result<int, int> = Err(404);
660
661         assert_eq!(ok.into_either(), either::Right(100));
662         assert_eq!(err.into_either(), either::Left(404));
663     }
664
665     #[test]
666     pub fn test_as_either() {
667         let ok: Result<int, int> = Ok(100);
668         let err: Result<int, int> = Err(404);
669
670         assert_eq!(ok.as_either().unwrap_right(), &100);
671         assert_eq!(err.as_either().unwrap_left(), &404);
672     }
673 }