rust_loguru/handler/
mod.rs1use parking_lot::RwLock;
2use std::fmt;
3use std::sync::Arc;
4
5use crate::formatters::Formatter;
6use crate::level::LogLevel;
7use crate::record::Record;
8
9pub type HandlerFilter = Arc<dyn Fn(&Record) -> bool + Send + Sync>;
10
11pub trait Handler: Send + Sync + fmt::Debug {
13 fn level(&self) -> LogLevel;
15
16 fn set_level(&mut self, level: LogLevel);
18
19 fn is_enabled(&self) -> bool;
21
22 fn set_enabled(&mut self, enabled: bool);
24
25 fn formatter(&self) -> &Formatter;
27
28 fn set_formatter(&mut self, formatter: Formatter);
30
31 fn set_filter(&mut self, filter: Option<HandlerFilter>);
33
34 fn filter(&self) -> Option<&HandlerFilter>;
36
37 fn handle(&self, record: &Record) -> Result<(), String>;
39
40 fn handle_batch(&self, records: &[Record]) -> Result<(), String> {
42 for record in records {
43 self.handle(record)?;
44 }
45 Ok(())
46 }
47
48 fn init(&mut self) -> Result<(), String> {
50 Ok(())
51 }
52 fn flush(&self) -> Result<(), String> {
54 Ok(())
55 }
56 fn shutdown(&mut self) -> Result<(), String> {
58 Ok(())
59 }
60}
61
62pub struct NullHandler {
64 level: LogLevel,
66 enabled: bool,
68 formatter: Formatter,
70 filter: Option<HandlerFilter>,
72}
73
74impl Default for NullHandler {
75 fn default() -> Self {
76 Self {
77 level: LogLevel::Info,
78 enabled: true,
79 formatter: Formatter::text(),
80 filter: None,
81 }
82 }
83}
84
85impl Handler for NullHandler {
86 fn level(&self) -> LogLevel {
87 self.level
88 }
89
90 fn set_level(&mut self, level: LogLevel) {
91 self.level = level;
92 }
93
94 fn is_enabled(&self) -> bool {
95 self.enabled
96 }
97
98 fn set_enabled(&mut self, enabled: bool) {
99 self.enabled = enabled;
100 }
101
102 fn formatter(&self) -> &Formatter {
103 &self.formatter
104 }
105
106 fn set_formatter(&mut self, formatter: Formatter) {
107 self.formatter = formatter;
108 }
109
110 fn set_filter(&mut self, filter: Option<HandlerFilter>) {
111 self.filter = filter;
112 }
113
114 fn filter(&self) -> Option<&HandlerFilter> {
115 self.filter.as_ref()
116 }
117
118 fn handle(&self, _record: &Record) -> Result<(), String> {
119 Ok(())
120 }
121}
122
123impl NullHandler {
124 pub fn new(level: LogLevel) -> Self {
125 Self {
126 level,
127 enabled: true,
128 formatter: Formatter::text(),
129 filter: None,
130 }
131 }
132}
133
134impl fmt::Debug for NullHandler {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 f.debug_struct("NullHandler")
137 .field("level", &self.level)
138 .field("enabled", &self.enabled)
139 .field("formatter", &self.formatter)
140 .finish()
141 }
142}
143
144pub mod console;
145pub mod file;
146pub mod network;
147
148pub type HandlerRef = Arc<RwLock<dyn Handler>>;
150
151pub fn new_handler_ref<H: Handler + 'static>(handler: H) -> HandlerRef {
153 Arc::new(RwLock::new(handler))
154}
155
156pub struct BaseHandler {
158 level: LogLevel,
160 enabled: bool,
162 formatter: Formatter,
164 filter: Option<HandlerFilter>,
166}
167
168impl BaseHandler {
169 pub fn new(level: LogLevel) -> Self {
171 Self {
172 level,
173 enabled: true,
174 formatter: Formatter::text(),
175 filter: None,
176 }
177 }
178}
179
180impl Handler for BaseHandler {
181 fn level(&self) -> LogLevel {
182 self.level
183 }
184
185 fn set_level(&mut self, level: LogLevel) {
186 self.level = level;
187 }
188
189 fn is_enabled(&self) -> bool {
190 self.enabled
191 }
192
193 fn set_enabled(&mut self, enabled: bool) {
194 self.enabled = enabled;
195 }
196
197 fn formatter(&self) -> &Formatter {
198 &self.formatter
199 }
200
201 fn set_formatter(&mut self, formatter: Formatter) {
202 self.formatter = formatter;
203 }
204
205 fn set_filter(&mut self, filter: Option<HandlerFilter>) {
206 self.filter = filter;
207 }
208
209 fn filter(&self) -> Option<&HandlerFilter> {
210 self.filter.as_ref()
211 }
212
213 fn handle(&self, record: &Record) -> Result<(), String> {
214 if !self.enabled || record.level() < self.level {
215 return Ok(());
216 }
217 Ok(())
218 }
219}
220
221impl fmt::Debug for BaseHandler {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 f.debug_struct("BaseHandler")
224 .field("level", &self.level)
225 .field("enabled", &self.enabled)
226 .field("formatter", &self.formatter)
227 .finish()
228 }
229}
230
231#[cfg(test)]
232mod tests {
233 use super::*;
234
235 #[test]
236 fn test_base_handler() {
237 let mut handler = BaseHandler::new(LogLevel::Info);
238 assert_eq!(handler.level(), LogLevel::Info);
239 assert!(handler.is_enabled());
240
241 handler.set_enabled(false);
243 assert!(!handler.is_enabled());
244 let record = Record::new(LogLevel::Info, "test", None::<String>, None::<String>, None);
245 assert!(handler.handle(&record).is_ok());
246
247 handler.set_enabled(true);
249 let debug_record = Record::new(
250 LogLevel::Debug,
251 "test",
252 None::<String>,
253 None::<String>,
254 None,
255 );
256 assert!(handler.handle(&debug_record).is_ok()); let info_record = Record::new(LogLevel::Info, "test", None::<String>, None::<String>, None);
259 assert!(handler.handle(&info_record).is_ok()); let formatter = Formatter::text();
263 handler.set_formatter(formatter);
264 assert!(handler.formatter().format(&info_record).contains("test"));
265 }
266}