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