1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//!
//! # Rust-Log: A simple and flexible Logging System for Rust.
//! We present you a simple but flexible logging system with many different levels of logging.
//!
//! [LogLevel] - structure containing logging levels
//!
//! [Logger] - a structure containing functions for logging.
//!
//! # Example
//! ```
//!fn main() {
//!   use rust_log::{Logger, LogLevel};
//!   let logger = Logger::new(LogLevel::Debug);
//!
//!   // use macros (more comfortable)
//!
//!   info!(logger, "This is an info message!");
//!   /*...*/
//!}
//!
//! ```
//!
//!
extern crate colored;
use chrono::Utc;
use colored::*;

#[derive(Copy, Clone)]
pub enum LogLevel {
    Debug,
    Info,
    Error,
    Warn,
    Fatal,
    Critical,
}

#[derive(Copy, Clone)]
pub struct Logger {
    level: LogLevel,
}

impl Logger {
    pub fn new(level: LogLevel) -> Self {
        Logger { level }
    }

    fn log(&self, level: LogLevel, message: &str) {
        if level as u8 >= self.level as u8 {
            let now = Utc::now();
            println!("[{}] {} - {}", level_to_string(level.clone()), now, message);
        }
    }

    pub fn debug(&self, message: &str) {
        self.log(LogLevel::Debug, message);
    }

    pub fn info(&self, message: &str) {
        self.log(LogLevel::Info, message);
    }

    pub fn error(&self, message: &str) {
        self.log(LogLevel::Error, message);
    }

    pub fn warn(&self, message: &str) {
        self.log(LogLevel::Warn, message);
    }

    pub fn fatal(&self, message: &str) {
        self.log(LogLevel::Fatal, message);
    }
    pub fn critical(&self, message: &str) {
        self.log(LogLevel::Critical, message);
    }
}

macro_rules! debug {
    ($logger:expr, $message:expr) => {
        $logger.debug($message);
    };
}

macro_rules! warn {
    ($logger:expr, $message:expr) => {
        $logger.warn($message);
    };
}

macro_rules! error {
    ($logger:expr, $message:expr) => {
        $logger.error($message);
    };
}

macro_rules! info {
    ($logger:expr, $message:expr) => {
        $logger.info($message);
    };
}

macro_rules! fatal {
    ($logger:expr, $message:expr) => {
        $logger.fatal($message);
    };
}

macro_rules! critical {
    ($logger:expr, $message:expr) => {
        $logger.critical($message);
    };
}

fn level_to_string(level: LogLevel) -> String {
    match level {
        LogLevel::Debug => format!("{}", "DEBUG".cyan().italic().underline()),
        LogLevel::Info => format!("{}", "INFO".green().bold()),
        LogLevel::Error => format!("{}", "ERROR".red().italic().bold()),
        LogLevel::Warn => format!("{}", "WARN".yellow().on_yellow().bold().dimmed()),
        LogLevel::Fatal => format!("{}", "FATAL".on_bright_red().white().bold().underline()),
        LogLevel::Critical => format!("{}", "CRITICAL".bright_red().bold().italic().underline()),
    }
}