diff --git a/Cargo.toml b/Cargo.toml index 3d8e8dd3..7d79968a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,4 +25,5 @@ default = ["termcolor"] [dependencies] log = { version = "0.4.*", features = ["std"] } termcolor = { version = "1.1.*", optional = true } +paris = { version = "1.5.7", optional = true } chrono = "0.4.1" diff --git a/README.md b/README.md index 2428131b..cfa4deb1 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,25 @@ simplelog = "^0.10.0" ``` to your `Cargo.toml` +## ANSI color and style support + +This crate can internally depend on a [paris](https://github.com/0x20F/paris) crate to provide support for ANSI color and styles. +To use this feature you need to set a _paris_ feature, like this: +``` +[dependencies] +simplelog = { version = "^0.10.0", features = ["paris"] } +``` +in your `Cargo.toml` + +After this you can use e.g. the following call: +```rust +info!("I can write bold text or use tags to color it"); +``` + +This will automatically generates terminal control sequences for desired styles. + +More formatting info: [paris crate documentation](https://github.com/0x20F/paris) + ## [Documentation](https://docs.rs/simplelog/) ## Contributing diff --git a/examples/custom_colors.rs b/examples/custom_colors.rs index f3c1a0ea..8d45a501 100644 --- a/examples/custom_colors.rs +++ b/examples/custom_colors.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "termcolor")] +#[cfg(all(feature = "termcolor", not(feature = "paris")))] use log::*; #[cfg(feature = "termcolor")] use simplelog::*; diff --git a/examples/default_colors.rs b/examples/default_colors.rs index 3c6984ce..1d8d141b 100644 --- a/examples/default_colors.rs +++ b/examples/default_colors.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "termcolor")] +#[cfg(all(feature = "termcolor", not(feature = "paris")))] use log::*; #[cfg(feature = "termcolor")] use simplelog::*; diff --git a/examples/rgb_colors.rs b/examples/rgb_colors.rs index 6cffa9cc..8fc1c15a 100644 --- a/examples/rgb_colors.rs +++ b/examples/rgb_colors.rs @@ -1,4 +1,8 @@ -#[cfg(all(not(target_family = "windows"), feature = "termcolor"))] +#[cfg(all( + not(target_family = "windows"), + feature = "termcolor", + not(feature = "paris") +))] use log::*; #[cfg(all(not(target_family = "windows"), feature = "termcolor"))] use simplelog::*; diff --git a/examples/usage.rs b/examples/usage.rs index 7e17295c..8d4959c3 100644 --- a/examples/usage.rs +++ b/examples/usage.rs @@ -1,3 +1,4 @@ +#[cfg(not(feature = "paris"))] use log::*; use simplelog::*; diff --git a/src/lib.rs b/src/lib.rs index b3fb2248..481404db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,9 +36,14 @@ pub use termcolor::{Color, ColorChoice}; pub use log::{Level, LevelFilter}; use log::Log; -#[cfg(test)] +#[cfg(all(test, not(feature = "paris")))] use log::*; +#[cfg(feature = "paris")] +pub(crate) mod paris_macros; +#[cfg(feature = "paris")] +pub extern crate paris; + /// Trait to have a common interface to obtain the Level of Loggers /// /// Necessary for CombinedLogger to calculate diff --git a/src/paris_macros/mod.rs b/src/paris_macros/mod.rs new file mode 100644 index 00000000..3baebcfb --- /dev/null +++ b/src/paris_macros/mod.rs @@ -0,0 +1,130 @@ +/// Logs a message at the info level. +/// +/// Passed data uses a colorize_string formatter from a `paris` crate, so it can +/// contains special tags for controlling ANSI colors and styles +/// More info: https://docs.rs/paris/1.5.7/paris/formatter/fn.colorize_string.html +/// +/// # Examples +/// +/// ```edition2018 +/// use log::info; +/// +/// # fn main() { +/// # struct Connection { port: u32, speed: f32 } +/// let conn_info = Connection { port: 40, speed: 3.20 }; +/// +/// info!("Connected to port {} at {} Mb/s", conn_info.port, conn_info.speed); +/// info!(target: "connection_events", "Successfull connection, port: {}, speed: {}", +/// conn_info.port, conn_info.speed); +/// # } +/// ``` +#[macro_export] +macro_rules! info { + ($($args:tt)+) => { + log::info!("{}", paris::formatter::colorize_string(format!($($args)*))); + }; +} + +/// Logs a message at the debug level. +/// +/// Passed data uses a colorize_string formatter from a `paris` crate, so it can +/// contains special tags for controlling ANSI colors and styles +/// More info: https://docs.rs/paris/1.5.7/paris/formatter/fn.colorize_string.html +/// +/// # Examples +/// +/// ```edition2018 +/// use log::debug; +/// +/// # fn main() { +/// # struct Position { x: f32, y: f32 } +/// let pos = Position { x: 3.234, y: -1.223 }; +/// +/// debug!("New position: x: {}, y: {}", pos.x, pos.y); +/// debug!(target: "app_events", "New position: x: {}, y: {}", pos.x, pos.y); +/// # } +/// ``` +#[macro_export] +macro_rules! debug { + ($($args:tt)+) => { + log::debug!("{}", paris::formatter::colorize_string(format!($($args)*))); + }; +} + +/// Logs a message at the trace level. +/// +/// Passed data uses a colorize_string formatter from a `paris` crate, so it can +/// contains special tags for controlling ANSI colors and styles +/// More info: https://docs.rs/paris/1.5.7/paris/formatter/fn.colorize_string.html +/// +/// # Examples +/// +/// ```edition2018 +/// use log::trace; +/// +/// # fn main() { +/// # struct Position { x: f32, y: f32 } +/// let pos = Position { x: 3.234, y: -1.223 }; +/// +/// trace!("Position is: x: {}, y: {}", pos.x, pos.y); +/// trace!(target: "app_events", "x is {} and y is {}", +/// if pos.x >= 0.0 { "positive" } else { "negative" }, +/// if pos.y >= 0.0 { "positive" } else { "negative" }); +/// # } +/// ``` +#[macro_export] +macro_rules! trace { + ($($args:tt)+) => { + log::trace!("{}", paris::formatter::colorize_string(format!($($args)*))); + }; +} + +/// Logs a message at the warn level. +/// +/// Passed data uses a colorize_string formatter from a `paris` crate, so it can +/// contains special tags for controlling ANSI colors and styles +/// More info: https://docs.rs/paris/1.5.7/paris/formatter/fn.colorize_string.html +/// +/// # Examples +/// +/// ```edition2018 +/// use log::warn; +/// +/// # fn main() { +/// let warn_description = "Invalid Input"; +/// +/// warn!("Warning! {}!", warn_description); +/// warn!(target: "input_events", "App received warning: {}", warn_description); +/// # } +/// ``` +#[macro_export] +macro_rules! warn { + ($($args:tt)+) => { + log::warn!("{}", paris::formatter::colorize_string(format!($($args)*))); + }; +} + +/// Logs a message at the error level. +/// +/// Passed data uses a colorize_string formatter from a `paris` crate, so it can +/// contains special tags for controlling ANSI colors and styles +/// More info: https://docs.rs/paris/1.5.7/paris/formatter/fn.colorize_string.html +/// +/// # Examples +/// +/// ```edition2018 +/// use log::error; +/// +/// # fn main() { +/// let (err_info, port) = ("No connection", 22); +/// +/// error!("Error: {} on port {}", err_info, port); +/// error!(target: "app_events", "App Error: {}, Port: {}", err_info, 22); +/// # } +/// ``` +#[macro_export] +macro_rules! error { + ($($args:tt)+) => { + log::error!("{}", paris::formatter::colorize_string(format!($($args)*))); + }; +}