use super::JsValue;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Level {
Trace,
Debug,
Log,
Info,
Warn,
Error,
}
impl std::fmt::Display for Level {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use Level::*;
let v = match self {
Trace => "trace",
Debug => "debug",
Log => "log",
Info => "info",
Warn => "warn",
Error => "error",
};
write!(f, "{}", v)
}
}
pub trait ConsoleBackend: std::panic::RefUnwindSafe + 'static {
fn log(&self, level: Level, values: Vec<JsValue>);
}
impl<F> ConsoleBackend for F
where
F: Fn(Level, Vec<JsValue>) + std::panic::RefUnwindSafe + 'static,
{
fn log(&self, level: Level, values: Vec<JsValue>) {
(self)(level, values);
}
}
#[cfg(feature = "log")]
mod log {
use super::{JsValue, Level};
pub struct LogConsole;
fn print_value(value: JsValue) -> String {
match value {
JsValue::Undefined => "undefined".to_string(),
JsValue::Null => "null".to_string(),
JsValue::Bool(v) => v.to_string(),
JsValue::Int(v) => v.to_string(),
JsValue::Float(v) => v.to_string(),
JsValue::String(v) => v,
JsValue::Array(values) => {
let parts = values
.into_iter()
.map(print_value)
.collect::<Vec<_>>()
.join(", ");
format!("[{}]", parts)
}
JsValue::Object(map) => {
let parts = map
.into_iter()
.map(|(key, value)| format!("{}: {}", key, print_value(value)))
.collect::<Vec<_>>()
.join(", ");
format!("{{{}}}", parts)
}
#[cfg(feature = "chrono")]
JsValue::Date(v) => v.to_string(),
#[cfg(feature = "bigint")]
JsValue::BigInt(v) => v.to_string(),
JsValue::__NonExhaustive => unreachable!(),
}
}
impl super::ConsoleBackend for LogConsole {
fn log(&self, level: Level, values: Vec<JsValue>) {
if values.is_empty() {
return;
}
let log_level = match level {
Level::Trace => log::Level::Trace,
Level::Debug => log::Level::Debug,
Level::Log => log::Level::Info,
Level::Info => log::Level::Info,
Level::Warn => log::Level::Warn,
Level::Error => log::Level::Error,
};
let msg = values
.into_iter()
.map(print_value)
.collect::<Vec<_>>()
.join(" ");
log::log!(log_level, "{}", msg);
}
}
}
#[cfg(feature = "log")]
pub use self::log::LogConsole;