emerald/logging/
engine.rs1use 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}