use std::fmt::{Debug, Display};
use tracing::{debug, error, info, warn};
pub trait ErrorPrinter {
fn log_error<M: Display>(self, message: M) -> Self;
fn log_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self;
fn warn_error<M: Display>(self, message: M) -> Self;
fn warn_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self;
fn debug_error<M: Display>(self, message: M) -> Self;
fn debug_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self;
fn info_error<M: Display>(self, message: M) -> Self;
fn info_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self;
}
impl<T, E: Debug> ErrorPrinter for Result<T, E> {
#[track_caller]
fn log_error<M: Display>(self, message: M) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
error!(caller, "{message}, error: {e:?}")
},
}
self
}
#[track_caller]
fn log_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
error!(caller, "{}, error: {e:?}", message_fn())
},
}
self
}
#[track_caller]
fn warn_error<M: Display>(self, message: M) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
warn!(caller, "{message}, error: {e:?}")
},
}
self
}
#[track_caller]
fn warn_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
warn!(caller, "{}, error: {e:?}", message_fn())
},
}
self
}
#[track_caller]
fn debug_error<M: Display>(self, message: M) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
debug!(caller, "{message}, error: {e:?}")
},
}
self
}
#[track_caller]
fn debug_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
debug!(caller, "{}, error: {e:?}", message_fn())
},
}
self
}
#[track_caller]
fn info_error<M: Display>(self, message: M) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
info!(caller, "{message}, error: {e:?}")
},
}
self
}
#[track_caller]
fn info_error_fn<M: Display, F: FnOnce() -> M>(self, message_fn: F) -> Self {
match &self {
Ok(_) => {},
Err(e) => {
let caller = get_caller();
info!(caller, "{}, error: {e:?}", message_fn())
},
}
self
}
}
pub trait OptionPrinter {
fn error_none<M: Display>(self, message: M) -> Self;
fn warn_none<M: Display>(self, message: M) -> Self;
fn debug_none<M: Display>(self, message: M) -> Self;
fn info_none<M: Display>(self, message: M) -> Self;
}
impl<T> OptionPrinter for Option<T> {
#[track_caller]
fn error_none<M: Display>(self, message: M) -> Self {
match &self {
Some(_) => {},
None => {
let caller = get_caller();
error!(caller, "{message}")
},
}
self
}
#[track_caller]
fn warn_none<M: Display>(self, message: M) -> Self {
match &self {
Some(_) => {},
None => {
let caller = get_caller();
warn!(caller, "{message}")
},
}
self
}
#[track_caller]
fn debug_none<M: Display>(self, message: M) -> Self {
match &self {
Some(_) => {},
None => {
let caller = get_caller();
debug!(caller, "{message}")
},
}
self
}
#[track_caller]
fn info_none<M: Display>(self, message: M) -> Self {
match &self {
Some(_) => {},
None => {
let caller = get_caller();
info!(caller, "{message}")
},
}
self
}
}
#[track_caller]
fn get_caller() -> String {
let location = std::panic::Location::caller();
format!("{}:{}", location.file(), location.line())
}