//! Checks the functionality of the `?` operator in various syntactic contexts.

//@ run-pass

#![allow(dead_code)]

use std::fs::File;
use std::io::{self, Read};
use std::num::ParseIntError;
use std::str::FromStr;

fn on_method() -> Result<i32, ParseIntError> {
    Ok("1".parse::<i32>()? + "2".parse::<i32>()?)
}

fn in_chain() -> Result<String, ParseIntError> {
    Ok("3".parse::<i32>()?.to_string())
}

fn on_call() -> Result<i32, ParseIntError> {
    fn parse<T: FromStr>(s: &str) -> Result<T, T::Err> {
        s.parse()
    }

    Ok(parse("4")?)
}

fn nested() -> Result<i32, ParseIntError> {
    Ok("5".parse::<i32>()?.to_string().parse()?)
}

fn on_path() -> Result<i32, ParseIntError> {
    let x = "6".parse::<i32>();

    Ok(x?)
}

fn on_macro() -> Result<i32, ParseIntError> {
    macro_rules! id {
        ($e:expr) => {
            $e
        };
    }

    Ok(id!("7".parse::<i32>())?)
}

fn on_parens() -> Result<i32, ParseIntError> {
    let x = "8".parse::<i32>();

    Ok((x)?)
}

fn on_block() -> Result<i32, ParseIntError> {
    let x = "9".parse::<i32>();

    Ok({ x }?)
}

fn on_field() -> Result<i32, ParseIntError> {
    struct Pair<A, B> {
        a: A,
        b: B,
    }

    let x = Pair { a: "10".parse::<i32>(), b: 0 };

    Ok(x.a?)
}

fn on_tuple_field() -> Result<i32, ParseIntError> {
    let x = ("11".parse::<i32>(), 0);

    Ok(x.0?)
}

fn on_try() -> Result<i32, ParseIntError> {
    let x = "12".parse::<i32>().map(|i| i.to_string().parse::<i32>());

    Ok(x??)
}

fn on_binary_op() -> Result<i32, ParseIntError> {
    let x = 13 - "14".parse::<i32>()?;
    let y = "15".parse::<i32>()? - 16;
    let z = "17".parse::<i32>()? - "18".parse::<i32>()?;

    Ok(x + y + z)
}

fn on_index() -> Result<i32, ParseIntError> {
    let x = [19];
    let y = "0".parse::<usize>();

    Ok(x[y?])
}

fn on_args() -> Result<i32, ParseIntError> {
    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<i32, ParseIntError> {
    Ok(if true { "22".parse::<i32>() } else { "23".parse::<i32>() }?)
}

fn on_if_let() -> Result<i32, ParseIntError> {
    Ok(if let Ok(..) = "24".parse::<i32>() { "25".parse::<i32>() } else { "26".parse::<i32>() }?)
}

fn on_match() -> Result<i32, ParseIntError> {
    Ok(match "27".parse::<i32>() {
        Err(..) => "28".parse::<i32>(),
        Ok(..) => "29".parse::<i32>(),
    }?)
}

fn tight_binding() -> Result<bool, ()> {
    fn ok<T>(x: T) -> Result<T, ()> {
        Ok(x)
    }

    let x = ok(true);
    Ok(!x?)
}

// just type check
fn merge_error() -> Result<i32, Error> {
    let mut s = String::new();

    File::open("foo.txt")?.read_to_string(&mut s)?;

    Ok(s.parse::<i32>()? + 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<io::Error> for Error {
    fn from(e: io::Error) -> Error {
        Error::Io(e)
    }
}

impl From<ParseIntError> for Error {
    fn from(e: ParseIntError) -> Error {
        Error::Parse(e)
    }
}
