use strum_macros::{Display, EnumString};
pub type YRes<T> = Result<T, YError>;
#[derive(Debug, EnumString, Display, Clone)]
pub enum YError {
Error(Vec<String>),
IOError(Vec<String>),
ParseError(Vec<String>),
DataBaseError(Vec<String>),
ConsistentError(Vec<String>),
BusinessError(Vec<String>),
}
impl YError {
pub fn get_context(&self) -> &Vec<String> {
match self {
YError::Error(context) |
YError::IOError(context) |
YError::ParseError(context) |
YError::DataBaseError(context) |
YError::ConsistentError(context) |
YError::BusinessError(context) => {
context
}
}
}
pub fn get_context_mut(&mut self) -> &mut Vec<String> {
match self {
YError::Error(context) |
YError::IOError(context) |
YError::ParseError(context) |
YError::ConsistentError(context) |
YError::DataBaseError(context) |
YError::BusinessError(context) => {
context
}
}
}
pub fn print(&self) {
println!("{:?}", self)
}
}
pub trait Trace {
fn trace(self, ctx: String) -> Self;
}
impl<T> Trace for YRes<T> {
fn trace(mut self, ctx: String) -> Self {
if let Err(err) = &mut self {
err.get_context_mut().push(ctx)
}
self
}
}
#[macro_export]
macro_rules! ctx {
() => {
format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!())
};
($process_and_influence:literal) => {
format!("{}, MODULE={}, FILE={}, LINE={}", $process_and_influence, module_path!(), file!(), line!())
};
($process_and_influence:literal:$reason:expr) => {
format!("{}: {}, MODULE={}, FILE={}, LINE={}", $process_and_influence, $reason, module_path!(), file!(), line!())
};
($process_and_influence:literal, $($value:expr),*) => {{
let mut ctx = format!("{}, ", $process_and_influence);
$(
let var_trace = format!("{}={:?}, ", stringify!($value), $value);
ctx.push_str(&var_trace);
)*
ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
ctx
}};
($($value:expr),*) => {{
let mut ctx = String::new();
$(
let var_trace = format!("{}={:?}, ", stringify!($value), $value);
ctx.push_str(&var_trace);
)*
ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
ctx
}};
($process_and_influence:literal:$reason:expr, $($value:expr),*) => {{
let mut ctx = format!("{}: {}, ", $process_and_influence, $reason);
$(
let var_trace = format!("{}={:?}, ", stringify!($value), $value);
ctx.push_str(&var_trace);
)*
ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
ctx
}};
}
#[macro_export]
macro_rules! err {
($error_type:ident) => {{
let ctx = format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!());
YError::$error_type(vec![ctx])
}};
($error_type:ident::$process_and_influence:literal) => {{
let ctx = format!("{}, MODULE={}, FILE={}, LINE={}", $process_and_influence, module_path!(), file!(), line!());
YError::$error_type(vec![ctx])
}};
($error_type:ident::$process_and_influence:literal:$reason:expr) => {{
let ctx = format!("{}: {}, MODULE={}, FILE={}, LINE={}", $process_and_influence, $reason, module_path!(), file!(), line!());
YError::$error_type(vec![ctx])
}};
($error_type:ident, $($value:expr),*) => {{
let mut ctx = String::new();
$(
let var_trace = format!("{}={:?}, ", stringify!($value), $value);
ctx.push_str(&var_trace);
)*
ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
YError::$error_type(vec![ctx])
}};
($error_type:ident::$process_and_influence:literal, $($value:expr),*) => {{
let mut ctx = format!("{}, ", $process_and_influence);
$(
let var_trace = format!("{}={:?}, ", stringify!($value), $value);
ctx.push_str(&var_trace);
)*
ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
YError::$error_type(vec![ctx])
}};
($error_type:ident::$process_and_influence:literal:$reason:expr, $($value:expr),*) => {{
let mut ctx = format!("{}: {}, ", $process_and_influence, $reason);
$(
let var_trace = format!("{}={:?}, ", stringify!($value), $value);
ctx.push_str(&var_trace);
)*
ctx.push_str(&format!("MODULE={}, FILE={}, LINE={}", module_path!(), file!(), line!()));
YError::$error_type(vec![ctx])
}};
}