error_chain/
quick_main.rs

1/// Convenient wrapper to be able to use `?` and such in the main. You can
2/// use it with a separated function:
3///
4/// ```
5/// # #[macro_use] extern crate error_chain;
6/// # error_chain! {}
7/// # fn main() {
8/// quick_main!(run);
9/// # }
10///
11/// fn run() -> Result<()> {
12///     Err("error".into())
13/// }
14/// ```
15///
16/// or with a closure:
17///
18/// ```
19/// # #[macro_use] extern crate error_chain;
20/// # error_chain! {}
21/// # fn main() {
22/// quick_main!(|| -> Result<()> {
23///     Err("error".into())
24/// });
25/// # }
26/// ```
27///
28/// You can also set the exit value of the process by returning a type that implements [`ExitCode`](trait.ExitCode.html):
29///
30/// ```
31/// # #[macro_use] extern crate error_chain;
32/// # error_chain! {}
33/// # fn main() {
34/// quick_main!(run);
35/// # }
36///
37/// fn run() -> Result<i32> {
38///     Err("error".into())
39/// }
40/// ```
41#[macro_export]
42macro_rules! quick_main {
43    ($main:expr) => {
44        fn main() {
45            use std::io::Write;
46
47            ::std::process::exit(match $main() {
48                Ok(ret) => $crate::ExitCode::code(ret),
49                Err(ref e) => {
50                    write!(
51                        &mut ::std::io::stderr(),
52                        "{}",
53                        $crate::ChainedError::display_chain(e)
54                    )
55                    .expect("Error writing to stderr");
56
57                    1
58                }
59            });
60        }
61    };
62}
63
64/// Represents a value that can be used as the exit status of the process.
65/// See [`quick_main!`](macro.quick_main.html).
66pub trait ExitCode {
67    /// Returns the value to use as the exit status.
68    fn code(self) -> i32;
69}
70
71impl ExitCode for i32 {
72    fn code(self) -> i32 {
73        self
74    }
75}
76
77impl ExitCode for () {
78    fn code(self) -> i32 {
79        0
80    }
81}