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}