1use chrono::Local;
2
3use crate::{
4 sinks::base::{LogLevels, LogMessage},
5 utils::{self},
6};
7use std::{collections::HashMap, error::Error};
8
9pub struct Handler {
10 sinks: Vec<Box<dyn LogMessage>>, log_level: u8, level_map: HashMap<LogLevels, u8>, }
14
15impl Handler {
16 pub fn new() -> Result<Self, Box<dyn Error>> {
17 Ok(Handler {
18 sinks: vec![],
19 log_level: 3, level_map: map_log_levels(),
21 })
22 }
23
24 pub fn add_sink(&mut self, sink: Box<dyn LogMessage>) {
25 self.sinks.push(sink)
27 }
28
29 pub fn set_sinks(&mut self, sinks: Vec<Box<dyn LogMessage>>) {
30 self.sinks = sinks
32 }
33
34 pub fn set_log_level(&mut self, new_log_level: LogLevels) {
35 self.log_level = *self.level_map.get(&new_log_level).unwrap();
36 }
37
38 fn log_to_sinks(&mut self, message: &str, log_level: LogLevels) {
39 let timestamp: chrono::DateTime<Local> = utils::generate_human_timestamp();
41
42 let message_log_level: u8 = *self.level_map.get(&log_level).unwrap();
43
44 if message_log_level >= self.log_level {
46 for s in self.sinks.iter_mut() {
47 s.log_message(&String::from(message), timestamp, &log_level);
48 }
49 }
50 }
51
52 pub fn debug(&mut self, message: &str) {
53 self.log_to_sinks(message, LogLevels::Debug);
54 }
55
56 pub fn info(&mut self, message: &str) {
57 self.log_to_sinks(message, LogLevels::Info);
58 }
59
60 pub fn warn(&mut self, message: &str) {
61 self.log_to_sinks(message, LogLevels::Warn);
62 }
63
64 pub fn error(&mut self, message: &str) {
65 self.log_to_sinks(message, LogLevels::Error);
66 }
67
68 pub fn fatal(&mut self, message: &str) {
69 self.log_to_sinks(message, LogLevels::Fatal);
70 }
71}
72
73fn map_log_levels() -> HashMap<LogLevels, u8> {
74 let mut level_map: HashMap<LogLevels, u8> = HashMap::new();
75 level_map.insert(LogLevels::Debug, 0);
76 level_map.insert(LogLevels::Info, 1);
77 level_map.insert(LogLevels::Warn, 2);
78 level_map.insert(LogLevels::Error, 3);
79 level_map.insert(LogLevels::Fatal, 4);
80 level_map
81}