diff --git a/Cargo.toml b/Cargo.toml index 320332e..e15b561 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,11 @@ version = "0.4" [dependencies.web-sys] version = "0.3" features = ["console"] + +[dependencies.wasm-bindgen] +version = "0.2" +optional = true + +[features] +default = [] +color = ["wasm-bindgen"] diff --git a/README.md b/README.md index 117fbd8..6e27d1d 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,19 @@ Rust's log levels map to the browser's console log in the following way. | `warn!()` | `console.warn()` | | `error!()` | `console.error()` | +## Colors + +The `"color"` feature adds styling to the log messages. + +`Cargo.toml` +```toml +console_log = { version = "0.1", features = ["color"] } +``` + +The styled log messages will be rendered as follows: + +![Styled log messages](img/log_messages_styled.png) + ## Code Size [Twiggy](https://github.com/rustwasm/twiggy) reports this library adding about diff --git a/img/log_messages_styled.png b/img/log_messages_styled.png new file mode 100644 index 0000000..8d07ea8 Binary files /dev/null and b/img/log_messages_styled.png differ diff --git a/src/lib.rs b/src/lib.rs index fb9353a..9b925c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,9 +18,9 @@ //! ``` //! //! # Log Levels -//! +//! //! Rust's log levels map to the browser's console log in the following way. -//! +//! //! | Rust | Web Console | //! |------------|-------------------| //! | `trace!()` | `console.debug()` | @@ -28,30 +28,43 @@ //! | `info!()` | `console.info()` | //! | `warn!()` | `console.warn()` | //! | `error!()` | `console.error()` | -//! +//! //! # Getting Fancy //! //! The feature set provided by this crate is intentionally very basic. If you need more flexible //! formatting of log messages (timestamps, file and line info, etc.) this crate can be used with //! the [`fern`] logger via the [`console_log::log`] function. //! +//! ## Colors +//! +//! The `"color"` feature adds styling to the log messages. +//! +//! `Cargo.toml` +//! ```toml +//! console_log = { version = "0.1", features = ["color"] } +//! ``` +//! +//! The styled log messages will be rendered as follows: +//! +//! ![Styled log messages](img/log_messages_styled.png) +//! //! # Code Size -//! +//! //! [Twiggy] reports this library adding about 180Kb to the size of a minimal wasm binary in a //! debug build. If you want to avoid this, mark the library as optional and conditionally //! initialize it in your code for non-release builds. -//! +//! //! `Cargo.toml` //! ```toml //! [dependencies] //! cfg_if = "0.1" //! log = "0.4" //! console_log = { version = "0.1", optional = true } -//! +//! //! [features] //! default = ["console_log"] //! ``` -//! +//! //! `lib.rs` //! ```rust,ignore //! use wasm_bindgen::prelude::*; @@ -67,16 +80,16 @@ //! fn init_log() {} //! } //! } -//! +//! //! #[wasm_bindgen] //! pub fn main() { //! init_log(); //! // ... //! } //! ``` -//! +//! //! # Limitations -//! +//! //! The file and line number information associated with the log messages reports locations from //! the shims generated by `wasm-bindgen`, not the location of the logger call. //! @@ -84,9 +97,19 @@ //! [`console_log::log`]: fn.log.html //! [`fern`]: https://docs.rs/fern -use log::{Log, Level, Record, Metadata, SetLoggerError}; +use log::{Level, Log, Metadata, Record, SetLoggerError}; use web_sys::console; +#[cfg(feature = "color")] +use wasm_bindgen::JsValue; + +#[cfg(feature = "color")] +const STYLE: style::Style<'static> = style::Style::default(); + +#[cfg(feature = "color")] +#[doc(hidden)] +mod style; + static LOGGER: WebConsoleLogger = WebConsoleLogger {}; struct WebConsoleLogger {} @@ -119,16 +142,60 @@ impl Log for WebConsoleLogger { /// .apply()?; /// ``` pub fn log(record: &Record) { - // pick the console.log() variant for the appropriate logging level - let console_log = match record.level() { - Level::Error => console::error_1, - Level::Warn => console::warn_1, - Level::Info => console::info_1, - Level::Debug => console::log_1, - Level::Trace => console::debug_1, - }; - - console_log(&format!("{}", record.args()).into()); + #[cfg(not(feature = "color"))] + { + // pick the console.log() variant for the appropriate logging level + let console_log = match record.level() { + Level::Error => console::error_1, + Level::Warn => console::warn_1, + Level::Info => console::info_1, + Level::Debug => console::log_1, + Level::Trace => console::debug_1, + }; + + console_log(&format!("{}", record.args()).into()); + } + + #[cfg(feature = "color")] + { + // pick the console.log() variant for the appropriate logging level + let console_log = match record.level() { + Level::Error => console::error_4, + Level::Warn => console::warn_4, + Level::Info => console::info_4, + Level::Debug => console::log_4, + Level::Trace => console::debug_4, + }; + + let message = { + let message = format!( + "%c{level}%c {file}:{line} %c\n{text}", + level = record.level(), + file = record.file().unwrap_or_else(|| record.target()), + line = record + .line() + .map_or_else(|| "[Unknown]".to_string(), |line| line.to_string()), + text = record.args(), + ); + JsValue::from(&message) + }; + + let level_style = { + let style_str = match record.level() { + Level::Trace => STYLE.trace, + Level::Debug => STYLE.debug, + Level::Info => STYLE.info, + Level::Warn => STYLE.warn, + Level::Error => STYLE.error, + }; + + JsValue::from(style_str) + }; + + let file_line_style = JsValue::from_str(STYLE.file_line); + let text_style = JsValue::from_str(STYLE.text); + console_log(&message, &level_style, &file_line_style, &text_style); + } } /// Initializes the global logger setting `max_log_level` to the given value. diff --git a/src/style.rs b/src/style.rs new file mode 100644 index 0000000..63af347 --- /dev/null +++ b/src/style.rs @@ -0,0 +1,33 @@ +/// Log message styling. +/// +/// Adapted from +pub(crate) struct Style<'s> { + pub trace: &'s str, + pub debug: &'s str, + pub info: &'s str, + pub warn: &'s str, + pub error: &'s str, + pub file_line: &'s str, + pub text: &'s str, +} + +impl Style<'static> { + /// Returns default style values. + pub const fn default() -> Self { + macro_rules! bg_color { + ($color:expr) => { + concat!("color: white; padding: 0 3px; background: ", $color, ";"); + }; + }; + + Style { + trace: bg_color!("gray"), + debug: bg_color!("blue"), + info: bg_color!("green"), + warn: bg_color!("orange"), + error: bg_color!("darkred"), + file_line: "font-weight: bold; color: inherit", + text: "background: inherit; color: inherit", + } + } +}