vit_logger 0.1.6

Simple Rust logger
Documentation
use lazy_static::lazy_static;
use log::{LevelFilter, Record};
use std::collections::HashMap;
use std::path::Path;

extern crate chrono;

use crate::config::Config;
use chrono::Local;
use colored::Colorize;

lazy_static! {
    pub static ref TYPE_ICONS: HashMap<LevelFilter, &'static str> = {
        let mut m = HashMap::new();
        m.insert(LevelFilter::Error, "\u{2717}");
        m.insert(LevelFilter::Warn, "\u{25EC}");
        m.insert(LevelFilter::Info, "\u{2756}");
        m.insert(LevelFilter::Debug, "\u{2713}");
        m.insert(LevelFilter::Trace, "\u{25C9}");
        m
    };
}

pub struct Formatter {
    level: LevelFilter,
    message: String,
    config: Config,
    file: Option<String>,
    line: Option<u32>,
}

impl<'a> Formatter {
    pub fn new(record: &Record, config: Config) -> Formatter {
        Formatter {
            level: record.level().to_level_filter(),
            message: record.args().to_string(),
            config,
            file: record.file().map(|f| f.to_string()),
            line: record.line(),
        }
    }
    pub fn format(&self) {
        let target = if self.config.target {
            format!("{}{} ", env!("CARGO_PKG_NAME").dimmed(), ":".dimmed())
        } else {
            "".to_string()
        };

        let time = self.get_local_time().dimmed();
        let left = if self.config.badge {
            format!("{} {target}{}", self.get_badge(), self.message)
        } else if self.config.icon {
            format!(
                "{} {target}{}",
                self.colorize(self.get_icon(self.level)),
                self.message
            )
        } else if self.config.text {
            format!("{} {target}{}", self.colorize(&self.level.to_string().to_lowercase()), self.message)
        } else {
            format!(
                "{} {target}{}",
                self.colorize(self.get_icon(self.level)),
                self.message
            )
        };

        let normalized_path = &self.file.as_deref().unwrap_or("").replace("\\", "/");
        let line = if self.line.is_some() {
            format!("{}{}", ":".dimmed(), self.line.unwrap().to_string().dimmed())
        } else {
            "".to_string()
        };

        let location = if self.config.file && self.config.line {
            format!(
                "{}{}",
                normalized_path.dimmed(),
                line
            )
        } else if self.config.file {
            format!("{}", normalized_path.dimmed())
        } else if self.config.line {
            format!("{}", line)
        } else {
            "".to_string()
        };

        let line = format!("{}{}{}", if self.config.time {
            format!(" {} ", time)
        } else {
            "".to_string()
        }, if location.is_empty() {
            "".to_string()
        } else {
            format!("{} ", location)
        }, left);

        if self.config.badge {
            println!("\n{}\n", line);
        } else {
            println!("{}", line);
        }
    }

    pub fn get_icon(&self, level: LevelFilter) -> &str {
        TYPE_ICONS.get(&level).unwrap_or(&"")
    }

    pub fn colorize(&self, msg: &str) -> colored::ColoredString {
        match self.level {
            LevelFilter::Off => msg.red(),
            LevelFilter::Error => msg.bright_red(),
            LevelFilter::Warn => msg.yellow(),
            LevelFilter::Info => msg.bright_cyan(),
            LevelFilter::Debug => msg.green(),
            LevelFilter::Trace => msg.bright_magenta(),
        }
    }

    pub fn colorize_badge(&self, msg: &str) -> colored::ColoredString {
        match self.level {
            LevelFilter::Off => msg.on_red(),
            LevelFilter::Error => msg.on_bright_red(),
            LevelFilter::Warn => msg.on_yellow(),
            LevelFilter::Info => msg.on_bright_cyan(),
            LevelFilter::Debug => msg.on_green(),
            LevelFilter::Trace => msg.on_bright_magenta(),
        }
    }

    pub fn get_local_time(&self) -> String {
        let date = Local::now();
        date.format("%H:%M:%S").to_string()
    }

    pub fn get_badge(&self) -> String {
        let level_name = match self.level {
            LevelFilter::Error => " error ",
            LevelFilter::Warn => " warn ",
            LevelFilter::Info => " info ",
            LevelFilter::Debug => " debug ",
            LevelFilter::Trace => " trace ",
            _ => "off",
        };

        self.colorize_badge(&level_name.to_uppercase())
            .black()
            .to_string()
    }
}