poly_logger/
log_formatter.rs1use strfmt::strfmt;
2use std::collections::HashMap;
3
4pub struct LogFormatter {
5 timestamp_format: &'static str,
7
8 msg_format: &'static str,
10
11 use_strfmt: bool,
14}
15
16type MsgResult = Result<String, strfmt::FmtError>;
18
19impl Clone for LogFormatter {
20 fn clone(&self) -> LogFormatter {
21 LogFormatter {
22 timestamp_format: self.timestamp_format.clone(),
23 msg_format: self.msg_format.clone(),
24 use_strfmt: self.use_strfmt,
25 }
26 }
27}
28
29impl LogFormatter {
30 pub fn new() -> Self {
31 LogFormatter {
32 timestamp_format: "%+",
33 msg_format: "",
34 use_strfmt: false,
35 }
36 }
37
38 pub fn timestamp_format(&mut self, format: &'static str) -> &mut Self {
40 self.timestamp_format = format;
41 self
42 }
43
44 pub fn msg_format(&mut self, format: &'static str) -> &mut Self {
45 self.use_strfmt = true;
47 self.msg_format = format;
48 self
49 }
50
51 pub fn msg(&self, record: &log::Record) -> MsgResult {
53 match self.use_strfmt {
58 false => {
59 Ok(self.default_msg(record))
60 },
61 true => {
62 self.custom_msg(record)
63 },
64 }
65 }
66
67 pub fn default_msg(&self, record: &log::Record) -> String {
68 format!(
69 "[{timestamp}] {level} [{file}:{line}] {args}",
70 timestamp=self.timestamp(),
71 level=record.metadata().level(),
72 file=self.file(record),
73 line=self.line(record),
74 args=record.args())
75 }
76
77 fn custom_msg(&self, record: &log::Record) -> MsgResult {
78 let mut vars = HashMap::new();
79 vars.insert("timestamp".to_string(), self.timestamp());
80 vars.insert("level".to_string(),
81 record.metadata().level().to_string());
82 vars.insert("file".to_string(), self.file(record));
83 vars.insert("line".to_string(), self.line(record).to_string());
84 vars.insert("args".to_string(), record.args().to_string());
85 strfmt(self.msg_format, &vars)
86 }
87
88 fn timestamp(&self) -> String {
89 match &self.timestamp_format {
90 &"" => {
91 "".to_string()
92 },
93 f => {
94 let now = chrono::Local::now();
99 now.format(&f).to_string()
100 }
101 }
102 }
103
104 fn line(&self, record: &log::Record) -> u32 {
105 match record.line() {
106 Some(l) => l,
107 None => 0,
108 }
109 }
110
111 fn file(&self, record: &log::Record) -> String {
112 match record.file() {
113 Some(f) => f.to_string(),
114 None => "<no_file>".to_string(),
115 }
116 }
117}