// run-pass #![allow(dead_code)] use std::fs::File; use std::io::{Read, self}; use std::num::ParseIntError; use std::str::FromStr; fn on_method() -> Result { Ok("1".parse::()? + "2".parse::()?) } fn in_chain() -> Result { Ok("3".parse::()?.to_string()) } fn on_call() -> Result { fn parse(s: &str) -> Result { s.parse() } Ok(parse("4")?) } fn nested() -> Result { Ok("5".parse::()?.to_string().parse()?) } fn on_path() -> Result { let x = "6".parse::(); Ok(x?) } fn on_macro() -> Result { macro_rules! id { ($e:expr) => { $e } } Ok(id!("7".parse::())?) } fn on_parens() -> Result { let x = "8".parse::(); Ok((x)?) } fn on_block() -> Result { let x = "9".parse::(); Ok({x}?) } fn on_field() -> Result { struct Pair { a: A, b: B } let x = Pair { a: "10".parse::(), b: 0 }; Ok(x.a?) } fn on_tuple_field() -> Result { let x = ("11".parse::(), 0); Ok(x.0?) } fn on_try() -> Result { let x = "12".parse::().map(|i| i.to_string().parse::()); Ok(x??) } fn on_binary_op() -> Result { let x = 13 - "14".parse::()?; let y = "15".parse::()? - 16; let z = "17".parse::()? - "18".parse::()?; Ok(x + y + z) } fn on_index() -> Result { let x = [19]; let y = "0".parse::(); Ok(x[y?]) } fn on_args() -> Result { fn sub(x: i32, y: i32) -> i32 { x - y } let x = "20".parse(); let y = "21".parse(); Ok(sub(x?, y?)) } fn on_if() -> Result { Ok(if true { "22".parse::() } else { "23".parse::() }?) } fn on_if_let() -> Result { Ok(if let Ok(..) = "24".parse::() { "25".parse::() } else { "26".parse::() }?) } fn on_match() -> Result { Ok(match "27".parse::() { Err(..) => "28".parse::(), Ok(..) => "29".parse::(), }?) } fn tight_binding() -> Result { fn ok(x: T) -> Result { Ok(x) } let x = ok(true); Ok(!x?) } // just type check fn merge_error() -> Result { let mut s = String::new(); File::open("foo.txt")?.read_to_string(&mut s)?; Ok(s.parse::()? + 1) } fn main() { assert_eq!(Ok(3), on_method()); assert_eq!(Ok("3".to_string()), in_chain()); assert_eq!(Ok(4), on_call()); assert_eq!(Ok(5), nested()); assert_eq!(Ok(6), on_path()); assert_eq!(Ok(7), on_macro()); assert_eq!(Ok(8), on_parens()); assert_eq!(Ok(9), on_block()); assert_eq!(Ok(10), on_field()); assert_eq!(Ok(11), on_tuple_field()); assert_eq!(Ok(12), on_try()); assert_eq!(Ok(-3), on_binary_op()); assert_eq!(Ok(19), on_index()); assert_eq!(Ok(-1), on_args()); assert_eq!(Ok(22), on_if()); assert_eq!(Ok(25), on_if_let()); assert_eq!(Ok(29), on_match()); assert_eq!(Ok(false), tight_binding()); } enum Error { Io(io::Error), Parse(ParseIntError), } impl From for Error { fn from(e: io::Error) -> Error { Error::Io(e) } } impl From for Error { fn from(e: ParseIntError) -> Error { Error::Parse(e) } }