#![allow(unused_variables)]
use core::fmt::{Debug,Display};
use log::Level;
use super::local;
pub trait LogError<T,E>:Sized{
fn log_level_with<F:FnOnce(E)->String>(self,level:Level,cb:F)->Option<T>;
#[inline(always)]
#[track_caller]
fn log_error_with<F:FnOnce(E)->String>(self,cb:F)->Option<T>{
self.log_level_with(Level::Error,cb)
}
#[inline(always)]
fn log_warn_with<F:FnOnce(E)->String>(self,cb:F)->Option<T>{
self.log_level_with(Level::Warn,cb)
}
#[inline(always)]
#[track_caller]
fn log_error(self,msg:&str)->Option<T>
where
E:Display,
{
self.log_error_with(|err|format!("{msg}:{err}"))
}
#[inline(always)]
#[track_caller]
fn log_error_detail(self,msg:&str)->Option<T>
where
E:Debug,
{
self.log_error_with(|err|format!("{msg}:{err:#?}"))
}
#[inline(always)]
#[track_caller]
fn log_warn(self,msg:&str)->Option<T>
where
E:Display,
{
self.log_warn_with(|err|format!("{msg}:{err}"))
}
#[inline(always)]
#[track_caller]
fn log_warn_detail(self,msg:&str)->Option<T>
where
E:Debug,
{
self.log_warn_with(|err|format!("{msg}:{err:#?}"))
}
}
impl<T,E> LogError<T,E> for Result<T,E>{
#[inline(always)]
#[track_caller]
fn log_level_with<F:FnOnce(E)->String>(self, level:Level,cb:F)->Option<T>{
match self {
Ok(res)=>Some(res),
Err(err)=>{
log_message(level,cb(err));
None
}
}
}
}
impl<T>LogError<T,&'static str> for Option<T>{
#[inline(always)]
#[track_caller]
fn log_level_with<F:FnOnce(&'static str)->String>(self,level:Level,cb:F)->Option<T>{
match self{
Some(res)=>Some(res),
None=>{
log_message(level,cb("None"));
None
}
}
}
}
#[track_caller]
fn log_message(level:Level,msg:String){
let loc = std::panic::Location::caller();
let file = loc.file();
let line = loc.line();
let err_str = format!("file:{:?},line:{:?},info:{:?}",file,line,msg);
print!("{:?}",err_str);
local::write_log_info(err_str);
}