muzzman_lib/
logger.rs

1use std::{
2    fs::File,
3    io::Write,
4    sync::{Arc, Mutex},
5};
6
7use crate::{
8    common::Common,
9    events::Event,
10    prelude::{ERef, LRef},
11    types::ID,
12};
13
14use bytes_kman::TBytes;
15
16#[derive(Clone, Debug, bytes_kman::Bytes)]
17pub enum Log {
18    Info(String),
19    Warning(String),
20    Error(String),
21}
22
23pub trait TLogger {
24    fn info(&mut self, data: impl Into<String>);
25    fn warn(&mut self, data: impl Into<String>);
26    fn error(&mut self, data: impl Into<String>);
27
28    fn flush(&mut self);
29    fn set_instant(&mut self, instant: bool);
30}
31
32pub trait TGetLogger {
33    fn get_logger(&self, dst: Option<Arc<Mutex<File>>>) -> Logger;
34}
35
36#[derive(Clone)]
37pub enum Ref {
38    Element(ERef),
39    Location(LRef),
40}
41
42impl From<Ref> for ID {
43    fn from(value: Ref) -> Self {
44        match value {
45            Ref::Element(e) => ID::Element(e.read().unwrap().id.clone()),
46            Ref::Location(l) => ID::Location(l.read().unwrap().id.clone()),
47        }
48    }
49}
50
51pub struct Logger {
52    dst: Option<Arc<Mutex<File>>>,
53    logs: Vec<Log>,
54    _ref: Ref,
55    instant: bool,
56}
57
58unsafe impl Sync for Logger {}
59unsafe impl Send for Logger {}
60
61impl Logger {
62    pub fn for_location(dst: Option<Arc<Mutex<File>>>, _ref: LRef) -> Self {
63        Self {
64            dst,
65            _ref: Ref::Location(_ref),
66            instant: false,
67            logs: Vec::new(),
68        }
69    }
70
71    pub fn for_element(dst: Option<Arc<Mutex<File>>>, _ref: ERef) -> Self {
72        Self {
73            dst,
74            _ref: Ref::Element(_ref),
75            instant: false,
76            logs: Vec::new(),
77        }
78    }
79}
80
81impl TLogger for Logger {
82    fn info(&mut self, data: impl Into<String>) {
83        let data: String = data.into();
84
85        if let Some(dst) = &self.dst {
86            let _ = write!(dst.lock().unwrap(), "Info: {data}");
87        }
88
89        self.logs.push(Log::Info(data));
90
91        if self.instant {
92            self.flush()
93        }
94    }
95
96    fn warn(&mut self, data: impl Into<String>) {
97        let data: String = data.into();
98
99        if let Some(dst) = &self.dst {
100            let _ = write!(dst.lock().unwrap(), "Warning: {data}");
101        }
102
103        self.logs.push(Log::Warning(data));
104
105        if self.instant {
106            self.flush()
107        }
108    }
109
110    fn error(&mut self, data: impl Into<String>) {
111        let data: String = data.into();
112
113        if let Some(dst) = &self.dst {
114            let _ = write!(dst.lock().unwrap(), "Error: {data}");
115        }
116
117        self.logs.push(Log::Error(data));
118
119        if self.instant {
120            self.flush()
121        }
122    }
123
124    fn flush(&mut self) {
125        for log in self.logs.iter() {
126            let _ = self
127                ._ref
128                .emit(Event::Log(self._ref.clone().into(), log.clone()));
129        }
130        self.logs.clear();
131    }
132
133    fn set_instant(&mut self, instant: bool) {
134        self.instant = instant;
135    }
136}
137
138impl Drop for Logger {
139    fn drop(&mut self) {
140        self.flush();
141    }
142}