1use std::{
4 fmt::Debug,
5 fs::OpenOptions,
6 io::Write,
7 time::SystemTime,
8};
9
10use crate::LogLevel;
11
12pub trait Handler {
13 fn trace(&mut self, message: String);
14 fn debug(&mut self, message: String);
15 fn info(&mut self, message: String);
16 fn warn(&mut self, message: String);
17 fn error(&mut self, message: String);
18 fn fatal(&mut self, message: String);
19}
20
21#[derive(Debug, Clone, PartialEq, PartialOrd)]
24pub struct FileHandler {
25 file: String,
26 log_buffer: Vec<String>,
27}
28
29impl FileHandler {
30 pub fn new(file: String) -> Self {
31 Self {
32 file,
33 log_buffer: Vec::new(),
34 }
35 }
36
37 fn log(&mut self, log_level: LogLevel, message: String) {
39 let timestamp = SystemTime::now()
40 .duration_since(SystemTime::UNIX_EPOCH)
41 .unwrap()
42 .as_secs();
43
44 let log_message = format!("[{}]-[{:?}]: {}", timestamp, log_level, message);
45
46 let colored_message = match log_level {
47 LogLevel::TRACE => format!("\x1B[37m{}\x1B[0m", log_message),
48 LogLevel::DEBUG => format!("\x1B[35m{}\x1B[0m", log_message),
49 LogLevel::INFO => format!("\x1B[32m{}\x1B[0m", log_message),
50 LogLevel::WARN => format!("\x1B[33m{}\x1B[0m", log_message),
51 LogLevel::ERROR => format!("\x1B[31;1m{}\x1B[0m", log_message),
52 LogLevel::FATAL => format!("\x1B[31;1m{}\x1B[0m", log_message),
53 };
54
55 self.log_buffer.push(colored_message);
56
57 if self.log_buffer.len() < 10 {
59 return;
60 }
61
62 let log_message = self.log_buffer.join("\n");
63
64 let mut file = OpenOptions::new()
65 .append(true)
66 .create(true)
67 .open(self.file.clone())
68 .unwrap();
69
70 file
71 .write_all(log_message.as_bytes())
72 .expect("Unable to write data");
73
74 self.log_buffer.clear();
75 }
76}
77
78impl Handler for FileHandler {
79 fn trace(&mut self, message: String) {
80 self.log(LogLevel::TRACE, message)
81 }
82
83 fn debug(&mut self, message: String) {
84 self.log(LogLevel::DEBUG, message)
85 }
86
87 fn info(&mut self, message: String) {
88 self.log(LogLevel::INFO, message)
89 }
90
91 fn warn(&mut self, message: String) {
92 self.log(LogLevel::WARN, message)
93 }
94
95 fn error(&mut self, message: String) {
96 self.log(LogLevel::ERROR, message)
97 }
98
99 fn fatal(&mut self, message: String) {
100 self.log(LogLevel::FATAL, message)
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, PartialOrd)]
105pub struct ConsoleHandler {
106 name: String,
107}
108
109impl ConsoleHandler {
110 pub fn new(name: &str) -> Self {
111 return Self {
112 name: name.to_string(),
113 };
114 }
115
116 fn log(&mut self, log_level: LogLevel, message: String) {
117 let timestamp = SystemTime::now()
118 .duration_since(SystemTime::UNIX_EPOCH)
119 .unwrap()
120 .as_secs();
121
122 let log_message = format!(
123 "[{}]-[{:?}]-[{}]: {}",
124 timestamp, log_level, self.name, message
125 );
126
127 let colored_message = match log_level {
128 LogLevel::TRACE => format!("\x1B[37m{}\x1B[0m", log_message),
129 LogLevel::DEBUG => format!("\x1B[35m{}\x1B[0m", log_message),
130 LogLevel::INFO => format!("\x1B[32m{}\x1B[0m", log_message),
131 LogLevel::WARN => format!("\x1B[33m{}\x1B[0m", log_message),
132 LogLevel::ERROR => format!("\x1B[31;1m{}\x1B[0m", log_message),
133 LogLevel::FATAL => format!("\x1B[31;1m{}\x1B[0m", log_message),
134 };
135
136 println!("{}", colored_message);
137 }
138}
139
140impl Handler for ConsoleHandler {
141 fn trace(&mut self, message: String) {
142 self.log(LogLevel::TRACE, message);
143 }
144
145 fn debug(&mut self, message: String) {
146 self.log(LogLevel::DEBUG, message);
147 }
148
149 fn info(&mut self, message: String) {
150 self.log(LogLevel::INFO, message);
151 }
152
153 fn warn(&mut self, message: String) {
154 self.log(LogLevel::WARN, message);
155 }
156
157 fn error(&mut self, message: String) {
158 self.log(LogLevel::ERROR, message);
159 }
160
161 fn fatal(&mut self, message: String) {
162 self.log(LogLevel::FATAL, message);
163 }
164}