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.
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.
11 //! A type representing either success or failure
13 #[allow(missing_doc)];
19 use option::{None, Option, Some, OptionIterator};
26 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
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
35 /// Contains the error value
39 impl<T, E: ToStr> Result<T, E> {
40 /// Get a reference to the value out of a successful result
44 /// If the result is an error
46 pub fn get_ref<'a>(&'a self) -> &'a T {
49 Err(ref e) => fail!("called `Result::get_ref()` on `Err` value: %s", e.to_str()),
53 /// Returns true if the result is `Ok`
55 pub fn is_ok(&self) -> bool {
62 /// Returns true if the result is `Err`
64 pub fn is_err(&self) -> bool {
68 /// Call a method based on a previous result
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
77 /// for buf in read_file(file) {
81 pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
88 /// Call a method based on a previous result
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.
95 pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
98 Err(ref t) => Some(t),
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.
106 pub fn unwrap(self) -> T {
109 Err(e) => fail!("called `Result::unwrap()` on `Err` value: %s", e.to_str()),
113 /// Unwraps a result, yielding the content of an `Err`.
114 /// Fails if the value is a `Ok`.
116 pub fn unwrap_err(self) -> E {
117 self.expect_err("called `Result::unwrap_err()` on `Ok` value")
120 /// Unwraps a result, yielding the content of an `Ok`.
121 /// Fails if the value is a `Err` with a custom failure message.
123 pub fn expect(self, reason: &str) -> T {
126 Err(_) => fail!(reason.to_owned()),
130 /// Unwraps a result, yielding the content of an `Err`
131 /// Fails if the value is a `Ok` with a custom failure message.
133 pub fn expect_err(self, reason: &str) -> E {
136 Ok(_) => fail!(reason.to_owned()),
140 /// Call a method based on a previous result
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.
149 /// let res = do read_file(file).map_move |buf| {
153 pub fn map_move<U>(self, op: &fn(T) -> U) -> Result<U,E> {
160 /// Call a method based on a previous result
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.
167 pub fn map_err_move<F>(self, op: &fn(E) -> F) -> Result<T,F> {
174 /// Call a method based on a previous result
176 /// If `self` is `Ok`, then `res` it is returned. If `self` is `Err`,
177 /// then `self` is returned.
179 pub fn and(self, res: Result<T, E>) -> Result<T, E> {
186 /// Call a method based on a previous result
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.
195 /// let res = do read_file(file) |buf| {
196 /// Ok(parse_bytes(buf))
199 pub fn and_then<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
206 /// Call a method based on a previous result
208 /// If `self` is `Ok`, then `self` is returned. If `self` is `Err`
209 /// then `res` is returned.
211 pub fn or(self, res: Result<T, E>) -> Result<T, E> {
218 /// Call a function based on a previous result
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.
225 pub fn or_else<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
233 impl<T: Clone, E: ToStr> Result<T, E> {
234 /// Call a method based on a previous result
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.
241 pub fn map_err<F: Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
243 Ok(ref t) => Ok(t.clone()),
244 Err(ref e) => Err(op(e))
249 impl<T, E: Clone + ToStr> Result<T, E> {
250 /// Call a method based on a previous result
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.
259 /// let res = do read_file(file).map |buf| {
263 pub fn map<U>(&self, op: &fn(&T) -> U) -> Result<U,E> {
265 Ok(ref t) => Ok(op(t)),
266 Err(ref e) => Err(e.clone())
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>;
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>;
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>;
289 impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
291 fn to_option(&self)-> Option<T> {
293 Ok(ref t) => Some(t.clone()),
299 impl<T, E> option::IntoOption<T> for Result<T, E> {
301 fn into_option(self)-> Option<T> {
309 impl<T, E> option::AsOption<T> for Result<T, E> {
311 fn as_option<'a>(&'a self)-> Option<&'a T> {
313 Ok(ref t) => Some(t),
319 impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
321 fn to_result(&self) -> Result<T, E> { self.clone() }
324 impl<T, E> IntoResult<T, E> for Result<T, E> {
326 fn into_result(self) -> Result<T, E> { self }
329 impl<T, E> AsResult<T, E> for Result<T, E> {
331 fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
334 Err(ref e) => Err(e),
339 impl<T: Clone, E: Clone> either::ToEither<E, T> for Result<T, E> {
341 fn to_either(&self)-> either::Either<E, T> {
343 Ok(ref t) => either::Right(t.clone()),
344 Err(ref e) => either::Left(e.clone()),
349 impl<T, E> either::IntoEither<E, T> for Result<T, E> {
351 fn into_either(self)-> either::Either<E, T> {
353 Ok(t) => either::Right(t),
354 Err(e) => either::Left(e),
359 impl<T, E> either::AsEither<E, T> for Result<T, E> {
361 fn as_either<'a>(&'a self)-> either::Either<&'a E, &'a T> {
363 Ok(ref t) => either::Right(t),
364 Err(ref e) => either::Left(e),
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> {
375 Some(ref t) => match op(t) {
376 Ok(v) => Ok(Some(v)),
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
387 /// Here is an example which increments every integer in a vector,
388 /// checking for overflow:
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); }
394 /// let v = [1u, 2, 3];
395 /// let res = collect(v.iter().map(|&x| inc_conditionally(x)));
396 /// assert!(res == Ok(~[2u, 3, 4]));
398 pub fn collect<T, E, Iter: Iterator<Result<T, E>>>(mut iterator: Iter)
400 let (lower, _) = iterator.size_hint();
401 let mut vs: ~[T] = vec::with_capacity(lower);
405 Err(u) => return Err(u)
411 /// Perform a fold operation over the result values from an iterator.
413 /// If an `Err` is encountered, it is immediately returned.
414 /// Otherwise, the folded value is returned.
417 Iter: Iterator<Result<T, E>>>(
424 Ok(v) => init = f(init, v),
425 Err(u) => return Err(u)
431 /// Perform a trivial fold operation over the result values
432 /// from an iterator.
434 /// If an `Err` is encountered, it is immediately returned.
435 /// Otherwise, a simple `Ok(())` is returned.
437 pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
440 fold(iterator, (), |_, _| ())
448 use either::{IntoEither, ToEither, AsEither};
451 use option::{IntoOption, ToOption, AsOption};
454 use vec::ImmutableVector;
456 pub fn op1() -> Result<int, ~str> { Ok(666) }
457 pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
461 assert_eq!(op1().and(Ok(667)).unwrap(), 667);
462 assert_eq!(op1().and(Err(~"bad")).unwrap_err(), ~"bad");
464 assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
465 assert_eq!(op2().and(Err(~"bad")).unwrap_err(), ~"sadface");
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");
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");
479 assert_eq!(op1().or(Ok(667)).unwrap(), 666);
480 assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);
482 assert_eq!(op2().or(Ok(667)).unwrap(), 667);
483 assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
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);
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!");
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; };
502 let errval = Err::<~str, ~str>(~"b");
503 do errval.iter().next().map |_| { valid = false; };
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 };
515 let errval = Err::<~str, ~str>(~"b");
516 do errval.iter_err().next().map |_| { valid = true };
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"));
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"));
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"));
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"));
545 pub fn test_get_ref_method() {
546 let foo: Result<int, ()> = Ok(100);
547 assert_eq!(*foo.get_ref(), 100);
552 assert_eq!(collect(range(0, 0)
553 .map(|_| Ok::<int, ()>(0))),
555 assert_eq!(collect(range(0, 3)
556 .map(|x| Ok::<int, ()>(x))),
558 assert_eq!(collect(range(0, 3)
559 .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
562 // test that it does not take more elements than it needs
563 let functions = [|| Ok(()), || Err(1), || fail!()];
565 assert_eq!(collect(functions.iter().map(|f| (*f)())),
571 assert_eq!(fold_(range(0, 0)
572 .map(|_| Ok::<(), ()>(()))),
574 assert_eq!(fold(range(0, 3)
575 .map(|x| Ok::<int, ()>(x)),
578 assert_eq!(fold_(range(0, 3)
579 .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
582 // test that it does not take more elements than it needs
583 let functions = [|| Ok(()), || Err(1), || fail!()];
585 assert_eq!(fold_(functions.iter()
591 pub fn test_to_option() {
592 let ok: Result<int, int> = Ok(100);
593 let err: Result<int, int> = Err(404);
595 assert_eq!(ok.to_option(), option::Some(100));
596 assert_eq!(err.to_option(), option::None);
600 pub fn test_into_option() {
601 let ok: Result<int, int> = Ok(100);
602 let err: Result<int, int> = Err(404);
604 assert_eq!(ok.into_option(), option::Some(100));
605 assert_eq!(err.into_option(), option::None);
609 pub fn test_as_option() {
610 let ok: Result<int, int> = Ok(100);
611 let err: Result<int, int> = Err(404);
613 assert_eq!(ok.as_option().unwrap(), &100);
614 assert_eq!(err.as_option(), option::None);
618 pub fn test_to_result() {
619 let ok: Result<int, int> = Ok(100);
620 let err: Result<int, int> = Err(404);
622 assert_eq!(ok.to_result(), Ok(100));
623 assert_eq!(err.to_result(), Err(404));
627 pub fn test_into_result() {
628 let ok: Result<int, int> = Ok(100);
629 let err: Result<int, int> = Err(404);
631 assert_eq!(ok.into_result(), Ok(100));
632 assert_eq!(err.into_result(), Err(404));
636 pub fn test_as_result() {
637 let ok: Result<int, int> = Ok(100);
638 let err: Result<int, int> = Err(404);
641 assert_eq!(ok.as_result(), Ok(&x));
644 assert_eq!(err.as_result(), Err(&x));
648 pub fn test_to_either() {
649 let ok: Result<int, int> = Ok(100);
650 let err: Result<int, int> = Err(404);
652 assert_eq!(ok.to_either(), either::Right(100));
653 assert_eq!(err.to_either(), either::Left(404));
657 pub fn test_into_either() {
658 let ok: Result<int, int> = Ok(100);
659 let err: Result<int, int> = Err(404);
661 assert_eq!(ok.into_either(), either::Right(100));
662 assert_eq!(err.into_either(), either::Left(404));
666 pub fn test_as_either() {
667 let ok: Result<int, int> = Ok(100);
668 let err: Result<int, int> = Err(404);
670 assert_eq!(ok.as_either().unwrap_right(), &100);
671 assert_eq!(err.as_either().unwrap_left(), &404);