use std::collections::HashMap;
use chrono::Local;
use crate::log_config::{Level, WD_LOG_CONFIG};
pub struct Output {
prefix: Vec<String>,
kv:Vec<String>,
}
impl Default for Output {
fn default() -> Self {
let mut log = Output::new();
if WD_LOG_CONFIG.print_time {
let now = Local::now().format("%Y-%m-%d %H:%M:%S%.3f ");
log = log.prefix(now);
}
return log
}
}
impl Output {
pub fn new()-> Output {
Self{prefix:vec![],kv :vec![]}
}
pub fn prefix<S : ToString>(mut self,s:S)->Self{
self.prefix.push(s.to_string());self
}
pub fn field<K : ToString,V:ToString>(mut self,key:K,val:V)->Self{
self.kv.push(key.to_string());
self.kv.push(val.to_string());
self
}
pub fn fields(mut self,map:HashMap<String,String>)->Self{
for (k,v) in map.into_iter() {
self.kv.push(k);
self.kv.push(v);
}
self
}
pub fn format(self,level:Level)->String{
let mut s = level.to_string();
s.push_str(" ");
for i in self.prefix.into_iter(){
s.push_str(i.as_str());
s.push_str(" ");
}
for i in self.kv.into_iter(){
if s.ends_with(" ") {
s.push_str( i.as_str());
}else{
s.push_str("=");
s.push_str( i.as_str());
s.push_str(" ");
}
}
let end = s.len();
s.remove(end -1);
return s
}
pub fn panic<S:ToString>(self,content:S){
Self::output(self,content,Level::PANIC)
}
pub fn error<S:ToString>(self,content:S){
Self::output(self,content,Level::ERROR)
}
pub fn warn<S:ToString>(self,content:S){
Self::output(self,content,Level::WARN)
}
pub fn info<S:ToString>(self,content:S){
Self::output(self,content,Level::INFO)
}
pub fn debug<S:ToString>(self,content:S){
Self::output(self,content,Level::DEBUG)
}
fn output<S:ToString>(self,content:S,level:Level){
let s = self.field("content",content.to_string()).format(level);
if WD_LOG_CONFIG.is_std_out {
match level {
Level::PANIC => println!("\x1b[7;31m{}\x1b[0m",s),
Level::ERROR => println!("\x1b[7;31m{}\x1b[0m",s),
Level::WARN => println!("\x1b[33m{}\x1b[0m",s),
Level::INFO => println!("\x1b[32m{}\x1b[0m",s),
Level::DEBUG => println!("\x1b[32m{}\x1b[0m",s),
}
}
if WD_LOG_CONFIG.is_file_out {
let mut out = WD_LOG_CONFIG.out.lock().unwrap();
if let Err(e) = out.write_all(s.as_bytes()) {
println!("write log to file error:{}",e);
}
}
}
}
pub fn log_prefix<S:ToString>(content:S)->Output{
Output::default().prefix(content)
}
pub fn log_field<K : ToString,V:ToString>(key:K,val:V)->Output{
Output::default().field(key,val)
}
pub fn log_fields(map:HashMap<String,String>)->Output{
Output::default().fields(map)
}