Skip to main content

windy_log4/log4/
mod.rs

1use std::rc::Rc;
2
3pub trait LogImpl {
4    fn info(&self, ss: &String);
5    fn warn(&self, ss: &String);
6    fn error(&self, ss: &String);
7}
8
9pub struct DefaultLogImpl {}
10impl LogImpl for DefaultLogImpl {
11    fn info(&self, ss: &String) {
12        println!("{}", ss);
13    }
14
15    fn warn(&self, ss: &String) {
16        println!("{}", ss);
17    }
18
19    fn error(&self, ss: &String) {
20        println!("{}", ss);
21    }
22}
23
24pub struct Log4 {
25    /// 日志对象是否启用
26    pub enable: bool,
27    /// 日志标签列表
28    tags: Vec<String>,
29    /// 日志IO代理
30    delegate: Rc<Box<dyn LogImpl>>,
31}
32
33unsafe impl Sync for Log4 {}
34
35impl Log4 {
36    pub fn new() -> Self {
37        let log = Log4 {
38            enable: true,
39            tags: Vec::new(),
40            delegate: Rc::new(Box::new(DefaultLogImpl {})),
41        };
42        return log;
43    }
44
45    pub fn set_log_impl(&mut self, delegate: Box<dyn LogImpl>) -> &mut Self {
46        self.delegate = Rc::new(delegate);
47        return self;
48    }
49
50    fn to_log_line<T: std::fmt::Debug>(&self, ss: T) -> String {
51        let tags_str: String = if (&self).tags.len() > 0 {
52            format!("[{}]", (&self).tags.join("]["))
53        } else {
54            "".to_string()
55        };
56        let content = format!("{} {:?}", tags_str, ss);
57        return content;
58    }
59    pub fn info<T: std::fmt::Debug>(&self, ss: T) {
60        if self.enable {
61            let content = self.to_log_line(ss);
62            self.delegate.info(&content);
63        }
64    }
65    pub fn warn<T: std::fmt::Debug>(&self, ss: T) {
66        if self.enable {
67            let content = self.to_log_line(ss);
68            self.delegate.warn(&content);
69        }
70    }
71
72    pub fn error<T: std::fmt::Debug>(&self, ss: T) {
73        if self.enable {
74            let content = self.to_log_line(ss);
75            self.delegate.error(&content);
76        }
77    }
78
79    pub fn add_tag<T: std::fmt::Debug>(&mut self, tag: T) -> &mut Log4 {
80        self.tags.push(format!("{:?}", tag));
81        return self;
82    }
83
84    pub fn fork(&self) -> Log4 {
85        let log4 = Log4 {
86            tags: self.tags.clone(),
87            delegate: self.delegate.clone(),
88            enable: self.enable,
89        };
90        return log4;
91    }
92}
93
94#[cfg(test)]
95mod test_log4 {
96    use super::{DefaultLogImpl, Log4};
97    use once_cell::sync::Lazy;
98
99    static mut MYLOG: Lazy<Log4> = Lazy::new(|| Log4::new());
100
101    static mut MYLOG22: Lazy<Log4> = Lazy::new(|| unsafe { MYLOG.fork() });
102
103    #[test]
104    fn test_log() {
105        let mut log = Log4::new();
106        let aaa: String = String::from("AAA");
107        let bbb: &String = &String::from("BBB");
108        log.add_tag(aaa).add_tag(bbb);
109        log.info("CCC");
110        // log.info("wklejweklfj");
111        log.info(String::from("DDD"));
112        log.info(bbb);
113
114        let mut log2 = log.fork();
115        log2.add_tag("fork1");
116        log2.info("EEE");
117        log2.warn("GGG");
118        log2.error("HHH");
119
120        log.info("III");
121        log.warn("JJJ");
122        log.error("KKK");
123
124        let mut log3 = log2.fork();
125        log3.info("log enabled");
126        log3.enable = false;
127        log3.info("this log shall not appear");
128        log3.enable = true;
129        log3.info("log enabled again");
130    }
131
132    #[test]
133    fn test_delete() {
134        let mut log = Log4::new();
135        log.set_log_impl(Box::new(DefaultLogImpl {}));
136        log.info("test delegate");
137    }
138
139    #[test]
140    fn test_static() {
141        unsafe {
142            MYLOG.info("static info");
143            MYLOG.warn("static warn");
144            MYLOG.error("static error");
145
146            let log2 = MYLOG.fork();
147            log2.info("fork static info");
148
149            MYLOG22.info("static fork info");
150        }
151    }
152}