emerald/logging/
engine.rs

1use crate::EmeraldError;
2
3use std::{
4    fs::{File, OpenOptions},
5    io::{prelude::*, LineWriter},
6};
7
8pub(crate) enum Log {
9    Info(String),
10    Warning(String),
11    Error(String),
12}
13
14const DEFAULT_LOG_FILE_PATH: &str = "./emerald.log";
15
16pub struct LoggingEngine {
17    logs: Vec<Log>,
18    line_writer: Option<LineWriter<File>>,
19}
20impl LoggingEngine {
21    pub(crate) fn new() -> Self {
22        let mut line_writer = None;
23
24        #[cfg(not(target_arch = "wasm32"))]
25        {
26            let file = OpenOptions::new()
27                .write(true)
28                .append(true)
29                .create(true)
30                .open(String::from(DEFAULT_LOG_FILE_PATH))
31                .unwrap();
32            line_writer = Some(LineWriter::new(file));
33        }
34
35        LoggingEngine {
36            logs: Vec::new(),
37            line_writer,
38        }
39    }
40
41    pub(crate) fn update(&mut self) -> Result<(), EmeraldError> {
42        if let Some(line_writer) = &mut self.line_writer {
43            for log in &self.logs {
44                match log {
45                    Log::Info(msg) => line_writer.write_all(msg.as_bytes())?,
46                    Log::Warning(msg) => line_writer.write_all(msg.as_bytes())?,
47                    Log::Error(msg) => line_writer.write_all(msg.as_bytes())?,
48                };
49
50                line_writer.write_all("\n".as_bytes())?;
51            }
52            line_writer.flush()?;
53        }
54
55        self.logs = Vec::with_capacity(self.logs.len());
56        Ok(())
57    }
58
59    fn log(&mut self, log: Log) {
60        self.logs.push(log);
61    }
62
63    pub fn info<T: Into<String>>(&mut self, msg: T) -> Result<(), EmeraldError> {
64        let log = Log::Info(msg.into());
65
66        self.log(log);
67        self.update()?;
68
69        Ok(())
70    }
71
72    pub fn warning<T: Into<String>>(&mut self, msg: T) -> Result<(), EmeraldError> {
73        let log = Log::Warning(msg.into());
74
75        self.log(log);
76        self.update()?;
77
78        Ok(())
79    }
80
81    pub fn error<T: Into<String>>(&mut self, msg: T) -> Result<(), EmeraldError> {
82        let log = Log::Error(msg.into());
83
84        self.log(log);
85        self.update()?;
86
87        Ok(())
88    }
89}