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!(&mut ::std::io::stderr(), "{}", $crate::ChainedError::display_chain(e))
51                        .expect("Error writing to stderr");
52
53                    1
54                }
55            });
56        }
57    };
58}
59
60/// Represents a value that can be used as the exit status of the process.
61/// See [`quick_main!`](macro.quick_main.html).
62pub trait ExitCode {
63    /// Returns the value to use as the exit status.
64    fn code(self) -> i32;
65}
66
67impl ExitCode for i32 {
68    fn code(self) -> i32 {
69        self
70    }
71}
72
73impl ExitCode for () {
74    fn code(self) -> i32 {
75        0
76    }
77}