rs_simple_logging/
write.rs

1use std::ops::DerefMut;
2use std::sync::Mutex;
3
4use crate::Severity;
5
6pub trait LogWrite: Sync + Send {
7    fn write(&self, serialized: &str, level: Severity);
8}
9
10struct LimitedWrite<L, S> {
11    writer: L,
12    state: Mutex<S>,
13}
14
15impl<L, S> LogWrite for LimitedWrite<L, S>
16where
17    L: LogWrite,
18    S: FnMut(Severity) -> bool + Sync + Send,
19{
20    fn write(&self, serialized: &str, level: Severity) {
21        match self.state.lock() {
22            Err(_) => {}
23            Ok(mut guard) => {
24                let state: &mut S = guard.deref_mut();
25                let log_available: bool = state(level);
26                match log_available {
27                    true => self.writer.write(serialized, level),
28                    false => {}
29                }
30            }
31        }
32    }
33}
34
35/// Creates a log writer which can ignore a log item.
36///
37/// # Arguments
38/// - original: The original log writer.
39/// - log_available: Checks if a log item for a severity can be accepted or not.
40pub fn limited_writer_new<L, S>(original: L, log_available: S) -> impl LogWrite
41where
42    L: LogWrite,
43    S: FnMut(Severity) -> bool + Sync + Send,
44{
45    LimitedWrite {
46        writer: original,
47        state: Mutex::new(log_available),
48    }
49}
50
51struct FnWrite<W, L> {
52    internal: W,
53    check_level: L,
54}
55
56impl<W, L> LogWrite for FnWrite<W, L>
57where
58    W: Fn(&str, Severity) + Sync + Send,
59    L: Fn(Severity) -> bool + Sync + Send,
60{
61    fn write(&self, serialized: &str, level: Severity) {
62        match (self.check_level)(level) {
63            false => {}
64            true => (self.internal)(serialized, level),
65        }
66    }
67}
68
69pub fn log_writer_new_from_fn<W, L>(internal: W, check_level: L) -> impl LogWrite
70where
71    W: Fn(&str, Severity) + Sync + Send,
72    L: Fn(Severity) -> bool + Sync + Send,
73{
74    FnWrite {
75        internal,
76        check_level,
77    }
78}
79
80pub fn log_writer_new_std_default_from_fn<L>(check_level: L) -> impl LogWrite
81where
82    L: Fn(Severity) -> bool + Sync + Send,
83{
84    log_writer_new_from_fn(
85        |serialized: &str, level: Severity| match level {
86            Severity::Trace => println!("{serialized}"),
87            Severity::Debug => println!("{serialized}"),
88            Severity::Info => println!("{serialized}"),
89            Severity::Warn => eprintln!("{serialized}"),
90            Severity::Error => eprintln!("{serialized}"),
91            Severity::Fatal => eprintln!("{serialized}"),
92        },
93        check_level,
94    )
95}
96
97pub fn level_checker_from_lower_bound(
98    lb_inclusive: Severity,
99) -> impl Fn(Severity) -> bool + Send + Sync {
100    let lbi: u8 = lb_inclusive.into();
101    move |level: Severity| {
102        let u: u8 = level.into();
103        lbi <= u
104    }
105}
106
107pub fn log_writer_new_std_default_from_lower_bound(lb_inclusive: Severity) -> impl LogWrite {
108    log_writer_new_std_default_from_fn(level_checker_from_lower_bound(lb_inclusive))
109}