result.rs 24.9 KB
Newer Older
C
Chris Wong 已提交
1
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
//! Error handling with the `Result` type
//!
//! `Result<T>` is the type used for returning and propagating
//! errors. It is an enum with the variants, `Ok(T)`, representing
//! success and containing a value, and `Err(E)`, representing error
//! and containing an error value.
//!
//! ~~~
//! enum Result<T, E> {
//!    Ok(T),
//!    Err(E)
//! }
//! ~~~
//!
//! Functions return `Result` whenever errors are expected and
//! recoverable. In the `std` crate `Result` is most prominently used
A
Alex Crichton 已提交
27
//! for [I/O](../../std/io/index.html).
28 29 30 31 32 33 34 35 36 37
//!
//! A simple function returning `Result` might be
//! defined and used like so:
//!
//! ~~~
//! #[deriving(Show)]
//! enum Version { Version1, Version2 }
//!
//! fn parse_version(header: &[u8]) -> Result<Version, &'static str> {
//!     if header.len() < 1 {
B
Brian Anderson 已提交
38
//!         return Err("invalid header length");
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
//!     }
//!     match header[0] {
//!         1 => Ok(Version1),
//!         2 => Ok(Version2),
//!         _ => Err("invalid version")
//!     }
//! }
//!
//! let version = parse_version(&[1, 2, 3, 4]);
//! match version {
//!     Ok(v) => {
//!         println!("working with version: {}", v);
//!     }
//!     Err(e) => {
//!         println!("error parsing header: {}", e);
//!     }
//! }
//! ~~~
//!
//! Pattern matching on `Result`s is clear and straightforward for
//! simple cases, but `Result` comes with some convenience methods
//! that make working it more succinct.
//!
//! ~~~
//! let good_result: Result<int, int> = Ok(10);
//! let bad_result: Result<int, int> = Err(10);
//!
//! // The `is_ok` and `is_err` methods do what they say.
//! assert!(good_result.is_ok() && !good_result.is_err());
//! assert!(bad_result.is_err() && !bad_result.is_ok());
//!
//! // `map` consumes the `Result` and produces another.
//! let good_result: Result<int, int> = good_result.map(|i| i + 1);
//! let bad_result: Result<int, int> = bad_result.map(|i| i - 1);
//!
//! // Use `and_then` to continue the computation.
//! let good_result: Result<bool, int> = good_result.and_then(|i| Ok(i == 11));
//!
//! // Use `or_else` to handle the error.
//! let bad_result: Result<int, int> = bad_result.or_else(|i| Ok(11));
//!
B
Brian Anderson 已提交
80
//! // Consume the result and return the contents with `unwrap`.
81 82 83 84 85
//! let final_awesome_result = good_result.ok().unwrap();
//! ~~~
//!
//! # Results must be used
//!
B
Brian Anderson 已提交
86 87 88 89 90 91 92
//! A common problem with using return values to indicate errors is
//! that it is easy to ignore the return value, thus failing to handle
//! the error. Result is annotated with the #[must_use] attribute,
//! which will cause the compiler to issue a warning when a Result
//! value is ignored. This makes `Result` especially useful with
//! functions that may encounter errors but don't otherwise return a
//! useful value.
93 94 95 96 97 98 99 100 101 102 103 104 105
//!
//! Consider the `write_line` method defined for I/O types
//! by the [`Writer`](../io/trait.Writer.html) trait:
//!
//! ~~~
//! use std::io::IoError;
//!
//! trait Writer {
//!     fn write_line(&mut self, s: &str) -> Result<(), IoError>;
//! }
//! ~~~
//!
//! *Note: The actual definition of `Writer` uses `IoResult`, which
J
Joseph Crail 已提交
106
//! is just a synonym for `Result<T, IoError>`.*
107
//!
108
//! This method doesn't produce a value, but the write may
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! fail. It's crucial to handle the error case, and *not* write
//! something like this:
//!
//! ~~~ignore
//! use std::io::{File, Open, Write};
//!
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
//! // If `write_line` errors, then we'll never know, because the return
//! // value is ignored.
//! file.write_line("important message");
//! drop(file);
//! ~~~
//!
//! If you *do* write that in Rust, the compiler will by give you a
//! warning (by default, controlled by the `unused_must_use` lint).
//!
//! You might instead, if you don't want to handle the error, simply
//! fail, by converting to an `Option` with `ok`, then asserting
//! success with `expect`. This will fail if the write fails, proving
//! a marginally useful message indicating why:
//!
B
Brian Anderson 已提交
130
//! ~~~no_run
131 132 133 134 135 136 137 138 139
//! use std::io::{File, Open, Write};
//!
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
//! file.write_line("important message").ok().expect("failed to write message");
//! drop(file);
//! ~~~
//!
//! You might also simply assert success:
//!
B
Brian Anderson 已提交
140
//! ~~~no_run
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
//! # use std::io::{File, Open, Write};
//!
//! # let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
//! assert!(file.write_line("important message").is_ok());
//! # drop(file);
//! ~~~
//!
//! Or propagate the error up the call stack with `try!`:
//!
//! ~~~
//! # use std::io::{File, Open, Write, IoError};
//! fn write_message() -> Result<(), IoError> {
//!     let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
//!     try!(file.write_line("important message"));
//!     drop(file);
//!     return Ok(());
//! }
//! ~~~
//!
//! # The `try!` macro
//!
//! When writing code that calls many functions that return the
//! `Result` type, the error handling can be tedious.  The `try!`
//! macro hides some of the boilerplate of propagating errors up the
//! call stack.
//!
//! It replaces this:
//!
//! ~~~
//! use std::io::{File, Open, Write, IoError};
//!
172
//! struct Info {
173
//!     name: String,
174 175 176
//!     age: int,
//!     rating: int
//! }
177 178 179 180
//!
//! fn write_info(info: &Info) -> Result<(), IoError> {
//!     let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
//!     // Early return on error
181
//!     match file.write_line(format!("name: {}", info.name).as_slice()) {
182 183 184
//!         Ok(_) => (),
//!         Err(e) => return Err(e)
//!     }
185
//!     match file.write_line(format!("age: {}", info.age).as_slice()) {
186 187 188
//!         Ok(_) => (),
//!         Err(e) => return Err(e)
//!     }
189
//!     return file.write_line(format!("rating: {}", info.rating).as_slice());
190 191 192 193 194 195 196 197
//! }
//! ~~~
//!
//! With this:
//!
//! ~~~
//! use std::io::{File, Open, Write, IoError};
//!
198
//! struct Info {
199
//!     name: String,
200 201 202
//!     age: int,
//!     rating: int
//! }
203 204 205 206
//!
//! fn write_info(info: &Info) -> Result<(), IoError> {
//!     let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
//!     // Early return on error
207 208 209
//!     try!(file.write_line(format!("name: {}", info.name).as_slice()));
//!     try!(file.write_line(format!("age: {}", info.age).as_slice()));
//!     try!(file.write_line(format!("rating: {}", info.rating).as_slice()));
210 211 212 213 214 215 216 217 218 219 220
//!     return Ok(());
//! }
//! ~~~
//!
//! *It's much nicer!*
//!
//! Wrapping an expression in `try!` will result in the unwrapped
//! success (`Ok`) value, unless the result is `Err`, in which case
//! `Err` is returned early from the enclosing function. Its simple definition
//! makes it clear:
//!
B
Brian Anderson 已提交
221 222
//! ~~~
//! # #![feature(macro_rules)]
223 224 225
//! macro_rules! try(
//!     ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
//! )
B
Brian Anderson 已提交
226
//! # fn main() { }
227 228 229 230 231 232 233 234 235 236
//! ~~~
//!
//! `try!` is imported by the prelude, and is available everywhere.
//!
//! # `Result` and `Option`
//!
//! The `Result` and [`Option`](../option/index.html) types are
//! similar and complementary: they are often employed to indicate a
//! lack of a return value; and they are trivially converted between
//! each other, so `Result`s are often handled by first converting to
237 238
//! `Option` with the [`ok`](type.Result.html#method.ok) and
//! [`err`](type.Result.html#method.ok) methods.
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
//!
//! Whereas `Option` only indicates the lack of a value, `Result` is
//! specifically for error reporting, and carries with it an error
//! value.  Sometimes `Option` is used for indicating errors, but this
//! is only for simple cases and is generally discouraged. Even when
//! there is no useful error value to return, prefer `Result<T, ()>`.
//!
//! Converting to an `Option` with `ok()` to handle an error:
//!
//! ~~~
//! use std::io::Timer;
//! let mut t = Timer::new().ok().expect("failed to create timer!");
//! ~~~
//!
//! # `Result` vs. `fail!`
//!
//! `Result` is for recoverable errors; `fail!` is for unrecoverable
//! errors. Callers should always be able to avoid failure if they
//! take the proper precautions, for example, calling `is_some()`
//! on an `Option` type before calling `unwrap`.
//!
//! The suitability of `fail!` as an error handling mechanism is
//! limited by Rust's lack of any way to "catch" and resume execution
//! from a thrown exception. Therefore using failure for error
H
Huon Wilson 已提交
263
//! handling requires encapsulating fallible code in a task. Calling
264 265
//! the `fail!` macro, or invoking `fail!` indirectly should be
//! avoided as an error reporting strategy. Failure is only for
J
Joseph Crail 已提交
266
//! unrecoverable errors and a failing task is typically the sign of
267 268 269 270 271 272 273 274 275
//! a bug.
//!
//! A module that instead returns `Results` is alerting the caller
//! that failure is possible, and providing precise control over how
//! it is handled.
//!
//! Furthermore, failure may not be recoverable at all, depending on
//! the context. The caller of `fail!` should assume that execution
//! will not resume after failure, that failure is catastrophic.
276

277
use clone::Clone;
278
use cmp::PartialEq;
279
use std::fmt::Show;
280
use iter::{Iterator, FromIterator};
M
Marvin Löbel 已提交
281
use option::{None, Option, Some};
282 283

/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
284 285
///
/// See the [`std::result`](index.html) module documentation for details.
286
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)]
287
#[must_use]
288
pub enum Result<T, E> {
M
Marvin Löbel 已提交
289
    /// Contains the success value
290
    Ok(T),
M
Marvin Löbel 已提交
291

292
    /// Contains the error value
293
    Err(E)
294 295
}

296 297 298 299
/////////////////////////////////////////////////////////////////////////////
// Type implementation
/////////////////////////////////////////////////////////////////////////////

M
Marvin Löbel 已提交
300
impl<T, E> Result<T, E> {
301 302 303
    /////////////////////////////////////////////////////////////////////////
    // Querying the contained values
    /////////////////////////////////////////////////////////////////////////
304

305
    /// Returns true if the result is `Ok`
306 307 308 309 310 311 312 313 314 315 316
    ///
    /// # Example
    ///
    /// ~~~
    /// use std::io::{File, Open, Write};
    ///
    /// # fn do_not_run_example() { // creates a file
    /// let mut file = File::open_mode(&Path::new("secret.txt"), Open, Write);
    /// assert!(file.write_line("it's cold in here").is_ok());
    /// # }
    /// ~~~
317
    #[inline]
E
Erick Tryzelaar 已提交
318 319 320 321 322 323
    pub fn is_ok(&self) -> bool {
        match *self {
            Ok(_) => true,
            Err(_) => false
        }
    }
324

325
    /// Returns true if the result is `Err`
326 327 328 329 330 331 332 333 334 335 336
    ///
    /// # Example
    ///
    /// ~~~
    /// use std::io::{File, Open, Read};
    ///
    /// // When opening with `Read` access, if the file does not exist
    /// // then `open_mode` returns an error.
    /// let bogus = File::open_mode(&Path::new("not_a_file.txt"), Open, Read);
    /// assert!(bogus.is_err());
    /// ~~~
337
    #[inline]
E
Erick Tryzelaar 已提交
338 339 340
    pub fn is_err(&self) -> bool {
        !self.is_ok()
    }
341

342

343
    /////////////////////////////////////////////////////////////////////////
M
Marvin Löbel 已提交
344
    // Adapter for each variant
345 346
    /////////////////////////////////////////////////////////////////////////

M
Marvin Löbel 已提交
347
    /// Convert from `Result<T, E>` to `Option<T>`
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
    ///
    /// Converts `self` into an `Option<T>`, consuming `self`,
    /// and discarding the error, if any.
    ///
    /// To convert to an `Option` without discarding the error value,
    /// use `as_ref` to first convert the `Result<T, E>` into a
    /// `Result<&T, &E>`.
    ///
    /// # Examples
    ///
    /// ~~~{.should_fail}
    /// use std::io::{File, IoResult};
    ///
    /// let bdays: IoResult<File> = File::open(&Path::new("important_birthdays.txt"));
    /// let bdays: File = bdays.ok().expect("unable to open birthday file");
    /// ~~~
364
    #[inline]
M
Marvin Löbel 已提交
365
    pub fn ok(self) -> Option<T> {
366
        match self {
M
Marvin Löbel 已提交
367 368
            Ok(x)  => Some(x),
            Err(_) => None,
369 370
        }
    }
371

M
Marvin Löbel 已提交
372
    /// Convert from `Result<T, E>` to `Option<E>`
373 374 375
    ///
    /// Converts `self` into an `Option<T>`, consuming `self`,
    /// and discarding the value, if any.
376
    #[inline]
M
Marvin Löbel 已提交
377
    pub fn err(self) -> Option<E> {
378
        match self {
M
Marvin Löbel 已提交
379 380
            Ok(_)  => None,
            Err(x) => Some(x),
381
        }
382 383
    }

M
Marvin Löbel 已提交
384 385 386 387 388
    /////////////////////////////////////////////////////////////////////////
    // Adapter for working with references
    /////////////////////////////////////////////////////////////////////////

    /// Convert from `Result<T, E>` to `Result<&T, &E>`
389 390 391
    ///
    /// Produces a new `Result`, containing a reference
    /// into the original, leaving the original in place.
392
    #[inline]
M
Marvin Löbel 已提交
393 394 395 396
    pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
        match *self {
            Ok(ref x) => Ok(x),
            Err(ref x) => Err(x),
397 398 399
        }
    }

M
Marvin Löbel 已提交
400
    /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
401
    #[inline]
M
Marvin Löbel 已提交
402 403 404 405
    pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
        match *self {
            Ok(ref mut x) => Ok(x),
            Err(ref mut x) => Err(x),
406 407
        }
    }
408

409 410 411 412
    /////////////////////////////////////////////////////////////////////////
    // Transforming contained values
    /////////////////////////////////////////////////////////////////////////

V
Virgile Andreani 已提交
413
    /// Maps a `Result<T, E>` to `Result<U, E>` by applying a function to an
414
    /// contained `Ok` value, leaving an `Err` value untouched.
415
    ///
416
    /// This function can be used to compose the results of two functions.
417
    ///
418 419 420 421 422 423 424 425 426 427 428 429
    /// # Examples
    ///
    /// Sum the lines of a buffer by mapping strings to numbers,
    /// ignoring I/O and parse errors:
    ///
    /// ~~~
    /// use std::io::{BufReader, IoResult};
    ///
    /// let buffer = "1\n2\n3\n4\n";
    /// let mut reader = BufReader::new(buffer.as_bytes());
    ///
    /// let mut sum = 0;
430
    ///
431
    /// while !reader.eof() {
432
    ///     let line: IoResult<String> = reader.read_line();
433 434
    ///     // Convert the string line to a number using `map` and `from_str`
    ///     let val: IoResult<int> = line.map(|line| {
435
    ///         from_str::<int>(line.as_slice().trim_right()).unwrap_or(0)
436 437 438 439
    ///     });
    ///     // Add the value if there were no errors, otherwise add 0
    ///     sum += val.ok().unwrap_or(0);
    /// }
440 441
    ///
    /// assert!(sum == 10);
442
    /// ~~~
443
    #[inline]
444
    pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
445 446 447 448 449 450
        match self {
          Ok(t) => Ok(op(t)),
          Err(e) => Err(e)
        }
    }

V
Virgile Andreani 已提交
451
    /// Maps a `Result<T, E>` to `Result<T, F>` by applying a function to an
452
    /// contained `Err` value, leaving an `Ok` value untouched.
453
    ///
454 455
    /// This function can be used to pass through a successful result while handling
    /// an error.
456
    #[inline]
457
    pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
458 459 460 461 462 463
        match self {
          Ok(t) => Ok(t),
          Err(e) => Err(op(e))
        }
    }

464 465 466 467 468 469 470
    ////////////////////////////////////////////////////////////////////////
    // Boolean operations on the values, eager and lazy
    /////////////////////////////////////////////////////////////////////////

    /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
    #[inline]
    pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
471 472
        match self {
            Ok(_) => res,
473
            Err(e) => Err(e),
474 475 476
        }
    }

477
    /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
478
    ///
479
    /// This function can be used for control flow based on result values
480
    #[inline]
481
    pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
482 483
        match self {
            Ok(t) => op(t),
484
            Err(e) => Err(e),
485
        }
486 487
    }

488
    /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
489 490 491 492 493 494 495 496
    #[inline]
    pub fn or(self, res: Result<T, E>) -> Result<T, E> {
        match self {
            Ok(_) => self,
            Err(_) => res,
        }
    }

497
    /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`.
498
    ///
499
    /// This function can be used for control flow based on result values
500
    #[inline]
501
    pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
502 503
        match self {
            Ok(t) => Ok(t),
504
            Err(e) => op(e),
505
        }
506
    }
507

M
Marvin Löbel 已提交
508
    /// Unwraps a result, yielding the content of an `Ok`.
509
    /// Else it returns `optb`.
510
    #[inline]
511
    pub fn unwrap_or(self, optb: T) -> T {
M
Marvin Löbel 已提交
512 513
        match self {
            Ok(t) => t,
514
            Err(_) => optb
M
Marvin Löbel 已提交
515 516 517
        }
    }

518
    /// Unwraps a result, yielding the content of an `Ok`.
519
    /// If the value is an `Err` then it calls `op` with its value.
520
    #[inline]
521
    pub fn unwrap_or_else(self, op: |E| -> T) -> T {
522 523
        match self {
            Ok(t) => t,
524
            Err(e) => op(e)
525 526
        }
    }
527 528 529 530 531 532 533

    /// Deprecated name for `unwrap_or_else()`.
    #[deprecated = "replaced by .unwrap_or_else()"]
    #[inline]
    pub fn unwrap_or_handle(self, op: |E| -> T) -> T {
        self.unwrap_or_else(op)
    }
534
}
535

536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
impl<T, E: Show> Result<T, E> {
    /// Unwraps a result, yielding the content of an `Ok`.
    ///
    /// Fails if the value is an `Err`.
    #[inline]
    pub fn unwrap(self) -> T {
        match self {
            Ok(t) => t,
            Err(e) =>
                fail!("called `Result::unwrap()` on an `Err` value: {}", e)
        }
    }
}

impl<T: Show, E> Result<T, E> {
    /// Unwraps a result, yielding the content of an `Err`.
    ///
    /// Fails if the value is an `Ok`.
    #[inline]
    pub fn unwrap_err(self) -> E {
        match self {
            Ok(t) =>
                fail!("called `Result::unwrap_err()` on an `Ok` value: {}", t),
            Err(e) => e
        }
    }
}

564 565 566 567
/////////////////////////////////////////////////////////////////////////////
// Free functions
/////////////////////////////////////////////////////////////////////////////

568 569 570
/// Takes each element in the `Iterator`: if it is an `Err`, no further
/// elements are taken, and the `Err` is returned. Should no `Err` occur, a
/// vector containing the values of each `Result` is returned.
571 572 573 574
///
/// Here is an example which increments every integer in a vector,
/// checking for overflow:
///
575 576 577 578 579 580 581 582 583 584 585
/// ```rust
/// use std::result;
/// use std::uint;
///
/// let v = vec!(1u, 2u);
/// let res: Result<Vec<uint>, &'static str> = result::collect(v.iter().map(|x: &uint|
///     if *x == uint::MAX { Err("Overflow!") }
///     else { Ok(x + 1) }
/// ));
/// assert!(res == Ok(vec!(2u, 3u)));
/// ```
586
#[inline]
587 588 589 590 591 592 593 594 595
pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Iter) -> Result<V, E> {
    // FIXME(#11084): This should be twice as fast once this bug is closed.
    let mut iter = iter.scan(None, |state, x| {
        match x {
            Ok(x) => Some(x),
            Err(err) => {
                *state = Some(err);
                None
            }
596
        }
597 598
    });

599
    let v: V = FromIterator::from_iter(iter.by_ref());
600 601 602 603

    match iter.state {
        Some(err) => Err(err),
        None => Ok(v),
604 605 606
    }
}

607
/// Perform a fold operation over the result values from an iterator.
608
///
609 610
/// If an `Err` is encountered, it is immediately returned.
/// Otherwise, the folded value is returned.
611
#[inline]
612 613 614
pub fn fold<T,
            V,
            E,
615 616 617
            Iter: Iterator<Result<T, E>>>(
            mut iterator: Iter,
            mut init: V,
618 619
            f: |V, T| -> V)
            -> Result<V, E> {
620 621 622 623
    for t in iterator {
        match t {
            Ok(v) => init = f(init, v),
            Err(u) => return Err(u)
624 625
        }
    }
626
    Ok(init)
627 628
}

629 630 631 632 633
/// Perform a trivial fold operation over the result values
/// from an iterator.
///
/// If an `Err` is encountered, it is immediately returned.
/// Otherwise, a simple `Ok(())` is returned.
634
#[inline]
635
pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
636
    fold(iterator, (), |_, _| ())
637 638
}

639 640 641
/////////////////////////////////////////////////////////////////////////////
// Tests
/////////////////////////////////////////////////////////////////////////////
642

643 644
#[cfg(test)]
mod tests {
645 646 647 648
    use realstd::vec::Vec;

    use result::{collect, fold, fold_};
    use prelude::*;
A
Alex Crichton 已提交
649
    use realstd::str::Str;
650
    use iter::range;
651

652 653
    pub fn op1() -> Result<int, &'static str> { Ok(666) }
    pub fn op2() -> Result<int, &'static str> { Err("sadface") }
654 655 656

    #[test]
    pub fn test_and() {
657
        assert_eq!(op1().and(Ok(667i)).unwrap(), 667);
658 659
        assert_eq!(op1().and(Err::<(), &'static str>("bad")).unwrap_err(),
                   "bad");
660

661
        assert_eq!(op2().and(Ok(667i)).unwrap_err(), "sadface");
662 663
        assert_eq!(op2().and(Err::<(),&'static str>("bad")).unwrap_err(),
                   "sadface");
664
    }
665

666 667
    #[test]
    pub fn test_and_then() {
668 669 670 671 672 673 674 675
        assert_eq!(op1().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap(), 667);
        assert_eq!(op1().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
                   "bad");

        assert_eq!(op2().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap_err(),
                   "sadface");
        assert_eq!(op2().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
                   "sadface");
676
    }
677 678

    #[test]
679 680
    pub fn test_or() {
        assert_eq!(op1().or(Ok(667)).unwrap(), 666);
681
        assert_eq!(op1().or(Err("bad")).unwrap(), 666);
682 683

        assert_eq!(op2().or(Ok(667)).unwrap(), 667);
684
        assert_eq!(op2().or(Err("bad")).unwrap_err(), "bad");
685 686 687
    }

    #[test]
688
    pub fn test_or_else() {
689 690
        assert_eq!(op1().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 666);
        assert_eq!(op1().or_else(|e| Err::<int, &'static str>(e)).unwrap(), 666);
691

692 693 694
        assert_eq!(op2().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 667);
        assert_eq!(op2().or_else(|e| Err::<int, &'static str>(e)).unwrap_err(),
                   "sadface");
695
    }
696 697

    #[test]
698
    pub fn test_impl_map() {
699 700
        assert!(Ok::<int, int>(1).map(|x| x + 1) == Ok(2));
        assert!(Err::<int, int>(1).map(|x| x + 1) == Err(1));
701 702 703
    }

    #[test]
704
    pub fn test_impl_map_err() {
705 706
        assert!(Ok::<int, int>(1).map_err(|x| x + 1) == Ok(1));
        assert!(Err::<int, int>(1).map_err(|x| x + 1) == Err(2));
707
    }
B
Brian Anderson 已提交
708

709 710
    #[test]
    fn test_collect() {
711
        let v: Result<Vec<int>, ()> = collect(range(0i, 0).map(|_| Ok::<int, ()>(0)));
712
        assert!(v == Ok(vec![]));
713

714
        let v: Result<Vec<int>, ()> = collect(range(0i, 3).map(|x| Ok::<int, ()>(x)));
715
        assert!(v == Ok(vec![0, 1, 2]));
716

717
        let v: Result<Vec<int>, int> = collect(range(0i, 3)
718
                                               .map(|x| if x > 1 { Err(x) } else { Ok(x) }));
719
        assert!(v == Err(2));
720 721

        // test that it does not take more elements than it needs
722
        let mut functions = [|| Ok(()), || Err(1i), || fail!()];
723

724
        let v: Result<Vec<()>, int> = collect(functions.mut_iter().map(|f| (*f)()));
725
        assert!(v == Err(1));
726 727 728 729
    }

    #[test]
    fn test_fold() {
730
        assert_eq!(fold_(range(0i, 0)
731 732
                        .map(|_| Ok::<(), ()>(()))),
                   Ok(()));
733
        assert_eq!(fold(range(0i, 3)
734 735 736
                        .map(|x| Ok::<int, ()>(x)),
                        0, |a, b| a + b),
                   Ok(3));
737
        assert_eq!(fold_(range(0i, 3)
738 739 740 741
                        .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
                   Err(2));

        // test that it does not take more elements than it needs
742
        let mut functions = [|| Ok(()), || Err(1i), || fail!()];
743

744
        assert_eq!(fold_(functions.mut_iter()
745 746 747
                        .map(|f| (*f)())),
                   Err(1));
    }
748

749 750
    #[test]
    pub fn test_fmt_default() {
751 752
        let ok: Result<int, &'static str> = Ok(100);
        let err: Result<int, &'static str> = Err("Err");
753

754 755 756 757
        let s = format!("{}", ok);
        assert_eq!(s.as_slice(), "Ok(100)");
        let s = format!("{}", err);
        assert_eq!(s.as_slice(), "Err(Err)");
758
    }
759 760 761

    #[test]
    pub fn test_unwrap_or() {
762
        let ok: Result<int, &'static str> = Ok(100i);
763
        let ok_err: Result<int, &'static str> = Err("Err");
764 765 766 767 768 769 770

        assert_eq!(ok.unwrap_or(50), 100);
        assert_eq!(ok_err.unwrap_or(50), 50);
    }

    #[test]
    pub fn test_unwrap_or_else() {
771 772
        fn handler(msg: &'static str) -> int {
            if msg == "I got this." {
773
                50i
774 775 776 777 778
            } else {
                fail!("BadBad")
            }
        }

779 780
        let ok: Result<int, &'static str> = Ok(100);
        let ok_err: Result<int, &'static str> = Err("I got this.");
781

782 783
        assert_eq!(ok.unwrap_or_else(handler), 100);
        assert_eq!(ok_err.unwrap_or_else(handler), 50);
784 785 786 787 788
    }

    #[test]
    #[should_fail]
    pub fn test_unwrap_or_else_failure() {
789 790
        fn handler(msg: &'static str) -> int {
            if msg == "I got this." {
791
                50i
792 793 794 795 796
            } else {
                fail!("BadBad")
            }
        }

797
        let bad_err: Result<int, &'static str> = Err("Unrecoverable mess.");
798
        let _ : int = bad_err.unwrap_or_else(handler);
799
    }
800
}