Hacker News new | ask | show | jobs
by tomjakubowski 4408 days ago
In addition to the (very handy) try! macro you can also map over Results and even chain monadic-like operations on them (either on the Ok or Err sides of a Result):

    enum FooError {
        XWasFalse,
        XWasUnknown
    }

    enum BarError {
        VectorTooLarge,
        FooErr(FooError)
    }

    fn foo(x: Option<bool>) -> Result<uint, FooError> {
        match x {
            Some(true) => Ok(42),
            Some(false) => Err(XWasFalse),
            _ => Err(XWasUnknown)
        }
    }

    fn bar() -> Result<Vec<uint>, BarError> {
        foo(None).or_else(|e| {
            // We can recover from an XWasUnknown error returned by
            // Foo, but not from a XWasFalse, so we return the error wrapped
            // in bar's error type.
            match e {
                XWasFalse => Err(FooErr(e)),
                XWasUnknown => Ok(99)
            }
        }).and_then(|n| {
            if n < 100 {
                let vec: Vec<()> = Vec::with_capacity(n);
                Ok(vec)
            } else {
                Err(VectorTooLarge)
            }
        }).map(|vec| {
            vec.iter().map(|_| { 42 }).collect()
        })
    }
edit: added a better example