1#[cfg(feature = "print-error")]
7extern crate termcolor;
8
9#[cfg(feature = "print-error")]
10use std::io;
11use std::fmt;
12use std::error::Error;
13#[cfg(feature = "print-error")]
14use std::io::Write;
15#[cfg(feature = "print-error")]
16use termcolor::{WriteColor, StandardStream, ColorSpec, Color};
17
18#[cfg(feature = "print-error")]
19pub trait PrintError {
21 fn print(&self, io: &mut StandardStream) -> io::Result<()>;
22}
23
24#[cfg(feature = "print-error")]
25impl<E: std::error::Error + ?Sized> PrintError for E {
26 fn print(&self, io: &mut StandardStream) -> io::Result<()> {
27 if let Some(cause) = self.source() {
28 cause.print(io)?;
29 }
30
31 io.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?;
32 write!(io, "error: ")?;
33
34 io.set_color(ColorSpec::new().set_fg(None))?;
35 writeln!(io, "{}", self)?;
36
37 Ok(())
38 }
39}
40
41pub trait ErrorCompat {
43 fn error_source(&self) -> Option<&(dyn Error + 'static)>;
44}
45
46trait CompatDisplayDebug: fmt::Display + fmt::Debug + ErrorCompat { }
47impl<T> CompatDisplayDebug for T where T: fmt::Display + fmt::Debug + ErrorCompat { }
48
49impl Error for dyn CompatDisplayDebug {
50 fn source(&self) -> Option<&(dyn Error + 'static)> {
51 self.error_source()
52 }
53}
54
55pub trait IntoErrorContext<Context, Target> {
60 fn into_target(self, ctx: Context) -> Target;
61}
62
63pub trait ErrorContext<Context, Target> {
67 fn context(self, ctx: Context) -> Target;
68 fn context_with<F: Fn() -> Context>(self, ctx: F) -> Target;
69}
70
71impl<Context, Target, T, E: IntoErrorContext<Context, Target>> ErrorContext<E, Result<T, Target>> for Result<T, Context> {
74 fn context(self, ctx: E) -> Result<T, Target> {
75 self.map_err(|x| ctx.into_target(x))
76 }
77
78 fn context_with<F: Fn() -> E>(self, ctx: F) -> Result<T, Target> {
79 self.map_err(|x| ctx().into_target(x))
80 }
81}
82
83#[macro_export]
85macro_rules! main_res {
86 ($main: ident) => {
87 fn main() {
88 if let Err(err) = $main() {
89 println!("{}", err);
90 }
91 }
92 };
93}
94
95#[macro_export]
97macro_rules! res {
98 ($err: ident) => {
99 type Res<T> = Result<T, $err>;
100 };
101 ($err: ident < $($arg: tt),* >) => {
102 type Res<$($arg),*, T> = Result<T, $err<$($arg),*>>;
103 };
104}