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}