Skip to content

Commit

Permalink
Refactor LogLevelWithColors into generic structure and test it.
Browse files Browse the repository at this point in the history
The test added ensures that WithColors behavior matches that which colored itself does. The main reason
we duplicate this behavior is so that we can format without doing any additional allocations.
  • Loading branch information
daboross committed Dec 22, 2017
1 parent 296910f commit f46c28d
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 15 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ before_script:
script:
- cargo build --verbose
- cargo test --verbose -- --skip test2 --skip test3
- cargo test test2
- cargo test test3
- cargo test --verbose test2
- cargo test --verbose test3
- cargo test --verbose --all-features -- --skip test2 --skip test3
- cargo run --example cmd-program
- cargo run --example cmd-program -- --verbose
- cargo run --example colored --features colored
5 changes: 3 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ install:
test_script:
- cargo build --verbose
- cargo test --verbose -- --skip test2 --skip test3
- cargo test test2
- cargo test test3
- cargo test --verbose test2
- cargo test --verbose test3
- cargo test --verbose --all-features -- --skip test2 --skip test3
- cargo run --example cmd-program
- cargo run --example cmd-program -- --verbose
- cargo run --example colored --features colored
Expand Down
71 changes: 60 additions & 11 deletions src/colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,31 @@ use log::LogLevel;
/// Extension crate allowing the use of `.colored` on LogLevels.
trait ColoredLogLevel {
/// Colors this log level with the given color.
fn colored(&self, color: Color) -> LogLevelWithColor;
fn colored(&self, color: Color) -> WithFgColor<LogLevel>;
}

/// Opaque structure representing a log level with an associated color. This implements [`fmt::Display`] so that it is
/// displayed as the underlying log level surrounded with ASCII markers for the given color.
/// Opaque structure which represents some text data and a color to display it with. This implements [`fmt::Display`]
/// via displaying the inner text (usually a log level) with ANSI color markers before to set the color and after to
/// reset the color.
///
/// WithFgColor instances can be created and displayed without any allocation.
// this is necessary in order to avoid using colored::ColorString, which has a Display
// implementation involving many allocations, and would involve two more string allocations
// even to create it.
pub struct LogLevelWithColor {
level: LogLevel,
pub struct WithFgColor<T>
where
T: fmt::Display,
{
text: T,
color: Color,
}

impl fmt::Display for LogLevelWithColor {
impl<T> fmt::Display for WithFgColor<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\x1B[{}m{}\x1B[0m", self.color.to_fg_str(), self.level)
write!(f, "\x1B[{}m{}\x1B[0m", self.color.to_fg_str(), self.text)
}
}

Expand Down Expand Up @@ -184,7 +193,7 @@ impl ColoredLogLevelConfig {
/// of support from the [`colored`] crate, this will not function in Windows.
///
/// [`colored`]: https://github.com/mackwic/colored
pub fn color(&self, level: LogLevel) -> LogLevelWithColor {
pub fn color(&self, level: LogLevel) -> WithFgColor<LogLevel> {
level.colored(self.get_color(&level))
}

Expand All @@ -201,10 +210,50 @@ impl ColoredLogLevelConfig {
}

impl ColoredLogLevel for LogLevel {
fn colored(&self, color: Color) -> LogLevelWithColor {
LogLevelWithColor {
level: *self,
fn colored(&self, color: Color) -> WithFgColor<LogLevel> {
WithFgColor {
text: *self,
color: color,
}
}
}

#[cfg(test)]
mod test {
use super::WithFgColor;
use colored::Colorize;
use colored::Color::*;

#[test]
fn fg_color_matches_colored_behavior() {
for &color in &[
Black,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
BrightBlack,
BrightRed,
BrightGreen,
BrightYellow,
BrightBlue,
BrightMagenta,
BrightCyan,
BrightWhite,
] {
assert_eq!(
format!("{}", "test".color(color)),
format!(
"{}",
WithFgColor {
text: "test",
color: color,
}
)
);
}
}
}

0 comments on commit f46c28d

Please sign in to comment.