rs_simple_logging/
copy.rs

1use std::ops::{Deref, DerefMut};
2use std::sync::Mutex;
3use std::time::SystemTime;
4
5use crate::{proxy::copy::Proxy, serialize::Serialize, write::LogWrite, Item, Severity};
6
7pub trait Logger: Sync + Send {
8    fn log(&self, item: Item);
9}
10
11pub fn logger_new_from_proxy<L, P>(original: L, proxy: P) -> impl Logger
12where
13    L: Logger,
14    P: Proxy + Sync + Send,
15{
16    logger_new_from_fn(move |old: Item| {
17        let neo: Item = proxy.get_item(old);
18        original.log(neo)
19    })
20}
21
22struct FnLogger<L> {
23    internal: L,
24}
25
26impl<L> Logger for FnLogger<L>
27where
28    L: Fn(Item) + Sync + Send,
29{
30    fn log(&self, item: Item) {
31        (self.internal)(item)
32    }
33}
34
35pub fn logger_new_from_fn<L>(internal: L) -> impl Logger
36where
37    L: Fn(Item) + Sync + Send,
38{
39    FnLogger { internal }
40}
41
42struct WriteSerialized<S, W> {
43    serialize: S,
44    write: W,
45}
46
47impl<S, W> Logger for WriteSerialized<S, W>
48where
49    S: Serialize,
50    W: LogWrite,
51{
52    fn log(&self, item: Item) {
53        let mut buf: String = String::new();
54        self.serialize.serialize(&item, &mut buf);
55        self.write.write(buf.as_str(), item.severity)
56    }
57}
58
59pub fn logger_new<S, W>(serialize: S, write: W) -> impl Logger
60where
61    S: Serialize,
62    W: LogWrite,
63{
64    WriteSerialized { serialize, write }
65}
66
67static _LOGGER: Mutex<Option<&dyn Logger>> = Mutex::new(None);
68
69impl Logger for Option<&dyn Logger> {
70    fn log(&self, item: Item) {
71        match self {
72            None => {}
73            Some(l) => l.log(item),
74        }
75    }
76}
77
78impl Logger for Mutex<Option<&dyn Logger>> {
79    fn log(&self, item: Item) {
80        match self.lock() {
81            Err(_) => {}
82            Ok(g) => {
83                let ro: &Option<_> = g.deref();
84                let o: Option<&dyn Logger> = ro.as_deref();
85                o.log(item)
86            }
87        }
88    }
89}
90
91impl Logger for Box<dyn Logger> {
92    fn log(&self, item: Item) {
93        let r = self.as_ref();
94        r.log(item)
95    }
96}
97
98fn _log(mut item: Item) {
99    item.timestamp = SystemTime::now();
100    _LOGGER.log(item)
101}
102
103pub fn log_trace(mut item: Item) {
104    item.severity = Severity::Trace;
105    _log(item)
106}
107
108pub fn log_debug(mut item: Item) {
109    item.severity = Severity::Debug;
110    _log(item)
111}
112
113pub fn log_info(mut item: Item) {
114    item.severity = Severity::Info;
115    _log(item)
116}
117
118pub fn log_warn(mut item: Item) {
119    item.severity = Severity::Warn;
120    _log(item)
121}
122
123pub fn log_error(mut item: Item) {
124    item.severity = Severity::Error;
125    _log(item)
126}
127
128pub fn log_fatal(mut item: Item) {
129    item.severity = Severity::Fatal;
130    _log(item)
131}
132
133pub fn set(neo: &'static dyn Logger) {
134    match _LOGGER.try_lock() {
135        Err(_) => {}
136        Ok(mut g) => {
137            let mo: &mut Option<_> = g.deref_mut();
138            mo.replace(neo);
139        }
140    }
141}
142
143pub fn set_boxed(neo: Box<dyn Logger>) {
144    set(Box::leak(neo))
145}