#[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),*>>;
};
}