captains_log/
formatter.rs

1use std::*;
2
3use log::{kv::Key, *};
4
5use crate::time::Timer;
6
7pub struct TimeFormatter<'a> {
8    pub now: &'a Timer,
9    pub fmt_str: &'a String,
10}
11
12impl<'a> TimeFormatter<'a> {
13    #[inline(always)]
14    fn time_str(&self) -> String {
15        self.now.format(&self.fmt_str).to_string()
16    }
17}
18
19pub struct FormatRecord<'a> {
20    pub record: &'a Record<'a>,
21    pub time: TimeFormatter<'a>,
22}
23
24impl<'a> FormatRecord<'a> {
25    #[inline(always)]
26    pub fn file(&self) -> &str {
27        basename(self.record.file().unwrap_or("<none>"))
28    }
29
30    #[inline(always)]
31    pub fn line(&self) -> u32 {
32        self.record.line().unwrap_or(0)
33    }
34
35    #[inline(always)]
36    pub fn time(&self) -> String {
37        self.time.time_str()
38    }
39
40    #[inline(always)]
41    pub fn key(&self, key: &str) -> String {
42        let source = self.record.key_values();
43        if let Some(v) = source.get(Key::from_str(key)) {
44            return format!(" ({})", v).to_string();
45        } else {
46            return "".to_string();
47        }
48    }
49
50    #[inline(always)]
51    pub fn level(&self) -> Level {
52        self.record.level()
53    }
54
55    #[inline(always)]
56    pub fn msg(&self) -> &'a fmt::Arguments<'a> {
57        self.record.args()
58    }
59}
60
61fn basename(path: &str) -> &str {
62    let res = path.rfind('/');
63    match res {
64        Some(idx) => path.get(idx + 1..).unwrap_or(path),
65        None => path,
66    }
67}