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]
42 macro_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).
62 pub trait ExitCode {
63     /// Returns the value to use as the exit status.
code(self) -> i3264     fn code(self) -> i32;
65 }
66 
67 impl ExitCode for i32 {
code(self) -> i3268     fn code(self) -> i32 {
69         self
70     }
71 }
72 
73 impl ExitCode for () {
code(self) -> i3274     fn code(self) -> i32 {
75         0
76     }
77 }
78