2016-09-05 19:29:40 +00:00
|
|
|
#[cfg(all(feature = "color", not(target_os = "windows")))]
|
|
|
|
use ansi_term::ANSIString;
|
2015-05-22 22:17:57 +00:00
|
|
|
|
2015-07-18 18:31:09 +00:00
|
|
|
#[cfg(all(feature = "color", not(target_os = "windows")))]
|
2015-10-28 14:23:59 +00:00
|
|
|
use ansi_term::Colour::{Green, Red, Yellow};
|
2015-05-22 22:17:57 +00:00
|
|
|
|
2017-05-17 09:56:37 +00:00
|
|
|
use std::env;
|
2018-08-02 03:13:51 +00:00
|
|
|
use std::fmt;
|
2016-05-30 08:07:44 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2020-03-19 07:17:52 +00:00
|
|
|
#[doc(hidden)]
|
2016-05-30 08:07:44 +00:00
|
|
|
pub enum ColorWhen {
|
|
|
|
Auto,
|
|
|
|
Always,
|
2016-09-05 19:29:40 +00:00
|
|
|
Never,
|
2016-05-30 08:07:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "color")]
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn is_a_tty(stderr: bool) -> bool {
|
2016-12-29 19:07:04 +00:00
|
|
|
debugln!("is_a_tty: stderr={:?}", stderr);
|
2017-02-19 16:12:55 +00:00
|
|
|
let stream = if stderr {
|
|
|
|
atty::Stream::Stderr
|
|
|
|
} else {
|
|
|
|
atty::Stream::Stdout
|
|
|
|
};
|
|
|
|
atty::is(stream)
|
2016-05-30 08:07:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(feature = "color"))]
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn is_a_tty(_: bool) -> bool {
|
2016-12-29 19:07:04 +00:00
|
|
|
debugln!("is_a_tty;");
|
2016-05-30 08:07:44 +00:00
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn is_term_dumb() -> bool {
|
2020-01-31 09:13:44 +00:00
|
|
|
env::var("TERM").ok() == Some(String::from("dumb"))
|
|
|
|
}
|
2017-05-26 22:25:38 +00:00
|
|
|
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) struct ColorizerOption {
|
|
|
|
pub(crate) use_stderr: bool,
|
|
|
|
pub(crate) when: ColorWhen,
|
2017-05-26 22:25:38 +00:00
|
|
|
}
|
|
|
|
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) struct Colorizer {
|
2017-05-27 16:23:25 +00:00
|
|
|
when: ColorWhen,
|
2016-05-30 08:07:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! color {
|
|
|
|
($_self:ident, $c:ident, $m:expr) => {
|
2017-05-26 22:33:56 +00:00
|
|
|
match $_self.when {
|
|
|
|
ColorWhen::Auto => Format::$c($m),
|
|
|
|
ColorWhen::Always => Format::$c($m),
|
|
|
|
ColorWhen::Never => Format::None($m),
|
2016-05-30 08:07:44 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Colorizer {
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn new(option: &ColorizerOption) -> Colorizer {
|
2017-05-26 22:25:38 +00:00
|
|
|
let is_a_tty = is_a_tty(option.use_stderr);
|
|
|
|
let is_term_dumb = is_term_dumb();
|
|
|
|
Colorizer {
|
2017-05-27 16:10:42 +00:00
|
|
|
when: if is_a_tty && !is_term_dumb {
|
|
|
|
option.when
|
2017-05-26 22:25:38 +00:00
|
|
|
} else {
|
|
|
|
ColorWhen::Never
|
2017-05-27 16:10:42 +00:00
|
|
|
},
|
2017-05-26 22:25:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn good<T>(&self, msg: T) -> Format<T>
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
T: fmt::Display + AsRef<str>,
|
2016-09-05 19:29:40 +00:00
|
|
|
{
|
2016-12-29 19:07:04 +00:00
|
|
|
debugln!("Colorizer::good;");
|
2016-05-30 08:07:44 +00:00
|
|
|
color!(self, Good, msg)
|
|
|
|
}
|
|
|
|
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn warning<T>(&self, msg: T) -> Format<T>
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
T: fmt::Display + AsRef<str>,
|
2016-09-05 19:29:40 +00:00
|
|
|
{
|
2016-12-29 19:07:04 +00:00
|
|
|
debugln!("Colorizer::warning;");
|
2016-05-30 08:07:44 +00:00
|
|
|
color!(self, Warning, msg)
|
|
|
|
}
|
|
|
|
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn error<T>(&self, msg: T) -> Format<T>
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
T: fmt::Display + AsRef<str>,
|
2016-09-05 19:29:40 +00:00
|
|
|
{
|
2016-12-29 19:07:04 +00:00
|
|
|
debugln!("Colorizer::error;");
|
2016-05-30 08:07:44 +00:00
|
|
|
color!(self, Error, msg)
|
|
|
|
}
|
|
|
|
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) fn none<T>(&self, msg: T) -> Format<T>
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
T: fmt::Display + AsRef<str>,
|
2016-09-05 19:29:40 +00:00
|
|
|
{
|
2016-12-29 19:07:04 +00:00
|
|
|
debugln!("Colorizer::none;");
|
2016-05-30 08:07:44 +00:00
|
|
|
Format::None(msg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Colorizer {
|
|
|
|
fn default() -> Self {
|
2018-11-14 17:12:34 +00:00
|
|
|
Colorizer::new(&ColorizerOption {
|
2017-05-27 16:10:42 +00:00
|
|
|
use_stderr: true,
|
|
|
|
when: ColorWhen::Auto,
|
2017-05-26 22:25:38 +00:00
|
|
|
})
|
2016-05-30 08:07:44 +00:00
|
|
|
}
|
|
|
|
}
|
2015-05-22 22:17:57 +00:00
|
|
|
|
2015-10-28 13:57:47 +00:00
|
|
|
/// Defines styles for different types of error messages. Defaults to Error=Red, Warning=Yellow,
|
|
|
|
/// and Good=Green
|
|
|
|
#[derive(Debug)]
|
2020-03-19 07:17:52 +00:00
|
|
|
pub(crate) enum Format<T> {
|
2015-10-28 13:57:47 +00:00
|
|
|
/// Defines the style used for errors, defaults to Red
|
2015-09-07 01:07:46 +00:00
|
|
|
Error(T),
|
2015-10-28 13:57:47 +00:00
|
|
|
/// Defines the style used for warnings, defaults to Yellow
|
2015-09-07 01:07:46 +00:00
|
|
|
Warning(T),
|
2015-10-28 13:57:47 +00:00
|
|
|
/// Defines the style used for good values, defaults to Green
|
2015-09-07 01:07:46 +00:00
|
|
|
Good(T),
|
2016-05-30 08:07:44 +00:00
|
|
|
/// Defines no formatting style
|
|
|
|
None(T),
|
2015-05-22 22:17:57 +00:00
|
|
|
}
|
|
|
|
|
2015-07-18 18:31:09 +00:00
|
|
|
#[cfg(all(feature = "color", not(target_os = "windows")))]
|
2015-05-22 22:17:57 +00:00
|
|
|
impl<T: AsRef<str>> Format<T> {
|
|
|
|
fn format(&self) -> ANSIString {
|
|
|
|
match *self {
|
|
|
|
Format::Error(ref e) => Red.bold().paint(e.as_ref()),
|
|
|
|
Format::Warning(ref e) => Yellow.paint(e.as_ref()),
|
|
|
|
Format::Good(ref e) => Green.paint(e.as_ref()),
|
2016-05-30 08:07:44 +00:00
|
|
|
Format::None(ref e) => ANSIString::from(e.as_ref()),
|
2015-05-22 22:17:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-18 18:31:09 +00:00
|
|
|
#[cfg(any(not(feature = "color"), target_os = "windows"))]
|
2015-05-22 22:17:57 +00:00
|
|
|
impl<T: fmt::Display> Format<T> {
|
|
|
|
fn format(&self) -> &T {
|
|
|
|
match *self {
|
|
|
|
Format::Error(ref e) => e,
|
|
|
|
Format::Warning(ref e) => e,
|
|
|
|
Format::Good(ref e) => e,
|
2016-05-30 08:07:44 +00:00
|
|
|
Format::None(ref e) => e,
|
2015-05-22 22:17:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-30 08:07:44 +00:00
|
|
|
#[cfg(all(feature = "color", not(target_os = "windows")))]
|
|
|
|
impl<T: AsRef<str>> fmt::Display for Format<T> {
|
2020-01-31 09:13:44 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{}", &self.format())
|
|
|
|
}
|
2016-05-30 08:07:44 +00:00
|
|
|
}
|
|
|
|
|
2015-07-18 18:31:09 +00:00
|
|
|
#[cfg(any(not(feature = "color"), target_os = "windows"))]
|
2015-05-22 22:17:57 +00:00
|
|
|
impl<T: fmt::Display> fmt::Display for Format<T> {
|
2020-01-31 09:13:44 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{}", &self.format())
|
|
|
|
}
|
2015-05-22 22:17:57 +00:00
|
|
|
}
|
2015-09-04 15:38:48 +00:00
|
|
|
|
2015-12-18 07:24:34 +00:00
|
|
|
#[cfg(all(test, feature = "color", not(target_os = "windows")))]
|
2015-09-04 15:38:48 +00:00
|
|
|
mod test {
|
2018-08-02 03:13:51 +00:00
|
|
|
use super::Format;
|
2016-05-30 08:07:44 +00:00
|
|
|
use ansi_term::ANSIString;
|
2016-09-05 19:29:40 +00:00
|
|
|
use ansi_term::Colour::{Green, Red, Yellow};
|
2015-09-04 15:38:48 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn colored_output() {
|
|
|
|
let err = Format::Error("error");
|
2017-11-28 12:30:06 +00:00
|
|
|
assert_eq!(
|
|
|
|
&*format!("{}", err),
|
|
|
|
&*format!("{}", Red.bold().paint("error"))
|
|
|
|
);
|
2015-09-04 15:38:48 +00:00
|
|
|
let good = Format::Good("good");
|
|
|
|
assert_eq!(&*format!("{}", good), &*format!("{}", Green.paint("good")));
|
|
|
|
let warn = Format::Warning("warn");
|
|
|
|
assert_eq!(&*format!("{}", warn), &*format!("{}", Yellow.paint("warn")));
|
2016-05-30 08:07:44 +00:00
|
|
|
let none = Format::None("none");
|
2017-11-28 12:30:06 +00:00
|
|
|
assert_eq!(
|
|
|
|
&*format!("{}", none),
|
|
|
|
&*format!("{}", ANSIString::from("none"))
|
|
|
|
);
|
2015-09-04 15:38:48 +00:00
|
|
|
}
|
2015-09-07 01:07:46 +00:00
|
|
|
}
|