1 use crate::util
::color
::ColorChoice
;
4 fmt
::{self, Display, Formatter}
,
8 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
9 pub(crate) enum Stream
{
14 #[derive(Clone, Debug)]
15 pub(crate) struct Colorizer
{
18 color_when
: ColorChoice
,
19 pieces
: Vec
<(String
, Style
)>,
24 pub(crate) fn new(stream
: Stream
, color_when
: ColorChoice
) -> Self {
33 pub(crate) fn good(&mut self, msg
: impl Into
<String
>) {
34 self.pieces
.push((msg
.into(), Style
::Good
));
38 pub(crate) fn warning(&mut self, msg
: impl Into
<String
>) {
39 self.pieces
.push((msg
.into(), Style
::Warning
));
43 pub(crate) fn error(&mut self, msg
: impl Into
<String
>) {
44 self.pieces
.push((msg
.into(), Style
::Error
));
49 pub(crate) fn hint(&mut self, msg
: impl Into
<String
>) {
50 self.pieces
.push((msg
.into(), Style
::Hint
));
54 pub(crate) fn none(&mut self, msg
: impl Into
<String
>) {
55 self.pieces
.push((msg
.into(), Style
::Default
));
61 #[cfg(feature = "color")]
62 pub(crate) fn print(&self) -> io
::Result
<()> {
63 use termcolor
::{BufferWriter, ColorChoice as DepColorChoice, ColorSpec, WriteColor}
;
65 let color_when
= match self.color_when
{
66 ColorChoice
::Always
=> DepColorChoice
::Always
,
67 ColorChoice
::Auto
if is_a_tty(self.stream
) => DepColorChoice
::Auto
,
68 _
=> DepColorChoice
::Never
,
71 let writer
= match self.stream
{
72 Stream
::Stderr
=> BufferWriter
::stderr(color_when
),
73 Stream
::Stdout
=> BufferWriter
::stdout(color_when
),
76 let mut buffer
= writer
.buffer();
78 for piece
in &self.pieces
{
79 let mut color
= ColorSpec
::new();
82 color
.set_fg(Some(termcolor
::Color
::Green
));
85 color
.set_fg(Some(termcolor
::Color
::Yellow
));
88 color
.set_fg(Some(termcolor
::Color
::Red
));
92 color
.set_dimmed(true);
97 buffer
.set_color(&color
)?
;
98 buffer
.write_all(piece
.0.as_bytes())?
;
102 writer
.print(&buffer
)
105 #[cfg(not(feature = "color"))]
106 pub(crate) fn print(&self) -> io
::Result
<()> {
107 // [e]println can't be used here because it panics
108 // if something went wrong. We don't want that.
111 let stdout
= std
::io
::stdout();
112 let mut stdout
= stdout
.lock();
113 write
!(stdout
, "{}", self)
116 let stderr
= std
::io
::stderr();
117 let mut stderr
= stderr
.lock();
118 write
!(stderr
, "{}", self)
124 /// Color-unaware printing. Never uses coloring.
125 impl Display
for Colorizer
{
126 fn fmt(&self, f
: &mut Formatter
) -> fmt
::Result
{
127 for piece
in &self.pieces
{
128 Display
::fmt(&piece
.0, f
)?
;
135 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
144 impl Default
for Style
{
145 fn default() -> Self {
150 #[cfg(feature = "color")]
151 fn is_a_tty(stream
: Stream
) -> bool
{
152 let stream
= match stream
{
153 Stream
::Stdout
=> atty
::Stream
::Stdout
,
154 Stream
::Stderr
=> atty
::Stream
::Stderr
,