use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError};
use crate::host::handler;
static LOGGER: HostLogger = HostLogger;
static LVL: [i32; 6] = [3, 2, 1, 0, -1, -1];
fn map_to_host(level: Level) -> i32 {
LVL[level as usize]
}
struct HostLogger;
impl Log for HostLogger {
#[inline]
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= log::max_level()
}
fn log(&self, record: &Record) {
if !self.enabled(record.metadata()) {
return;
}
handler::log(
map_to_host(record.metadata().level()),
format!("{}", record.args()).as_bytes(),
);
}
fn flush(&self) {}
}
#[inline]
pub fn init_with_level(level: Level) -> Result<(), SetLoggerError> {
log::set_max_level(max_level(level.to_level_filter()));
log::set_logger(&LOGGER)?;
Ok(())
}
fn max_level(level: LevelFilter) -> LevelFilter {
if handler::log_enabled(level.to_level().map_or_else(|| 3, map_to_host)) {
level
} else {
level.decrement_severity()
}
}
#[inline]
pub fn init() -> Result<(), SetLoggerError> {
init_with_level(Level::Info)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_init_log_with_level() {
let sut = init_with_level(Level::Info);
assert!(sut.is_ok());
assert_eq!(log::max_level(), LevelFilter::Info);
}
}