Skip to main content

forge/
log.rs

1mod util;
2
3use sys::log::Level as SysLevel;
4use sys::log::{forge_log, forge_log_getLevel};
5
6pub mod prelude {
7    pub use log::{debug, error, info, trace, warn};
8}
9
10use core::fmt::Write;
11use util::FixedCStringWriter;
12
13struct ForgeLogger;
14static LOGGER: ForgeLogger = ForgeLogger;
15
16const LOG_FORMAT: &[u8; 3] = b"%s\0";
17
18pub fn init() -> Result<(), log::SetLoggerError> {
19    log::set_logger(&LOGGER)?;
20    log::set_max_level(log::LevelFilter::Trace);
21    Ok(())
22}
23
24impl log::Log for ForgeLogger {
25    fn enabled(&self, metadata: &log::Metadata) -> bool {
26        let sys_level = Self::to_sys_level(metadata.level());
27        let current_level = unsafe { forge_log_getLevel() };
28        sys_level as u8 >= current_level as u8
29    }
30
31    fn log(&self, record: &log::Record) {
32        if !self.enabled(record.metadata()) {
33            return;
34        }
35
36        let sys_level = Self::to_sys_level(record.level());
37        let mut message = [0u8; 512];
38        let mut writer = FixedCStringWriter::new(&mut message);
39
40        let _ = write!(writer, "{}", record.args());
41
42        unsafe {
43            forge_log(sys_level, LOG_FORMAT.as_ptr().cast(), writer.as_c_str_ptr());
44        }
45    }
46
47    fn flush(&self) {}
48}
49
50impl ForgeLogger {
51    fn to_sys_level(level: log::Level) -> SysLevel {
52        match level {
53            log::Level::Error => SysLevel::Error,
54            log::Level::Warn => SysLevel::Warn,
55            log::Level::Info => SysLevel::Info,
56            log::Level::Debug => SysLevel::Debug,
57            log::Level::Trace => SysLevel::Debug,
58        }
59    }
60}