| use crate::builder::StyledStr; |
| use crate::util::color::ColorChoice; |
| |
| #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
| pub(crate) enum Stream { |
| Stdout, |
| Stderr, |
| } |
| |
| #[derive(Clone, Debug)] |
| pub(crate) struct Colorizer { |
| stream: Stream, |
| #[allow(unused)] |
| color_when: ColorChoice, |
| content: StyledStr, |
| } |
| |
| impl Colorizer { |
| pub(crate) fn new(stream: Stream, color_when: ColorChoice) -> Self { |
| Colorizer { |
| stream, |
| color_when, |
| content: Default::default(), |
| } |
| } |
| |
| pub(crate) fn with_content(mut self, content: StyledStr) -> Self { |
| self.content = content; |
| self |
| } |
| } |
| |
| /// Printing methods. |
| impl Colorizer { |
| #[cfg(feature = "color")] |
| pub(crate) fn print(&self) -> std::io::Result<()> { |
| let color_when = match self.color_when { |
| ColorChoice::Always => anstream::ColorChoice::Always, |
| ColorChoice::Auto => anstream::ColorChoice::Auto, |
| ColorChoice::Never => anstream::ColorChoice::Never, |
| }; |
| |
| let mut stdout; |
| let mut stderr; |
| let writer: &mut dyn std::io::Write = match self.stream { |
| Stream::Stderr => { |
| stderr = anstream::AutoStream::new(std::io::stderr().lock(), color_when); |
| &mut stderr |
| } |
| Stream::Stdout => { |
| stdout = anstream::AutoStream::new(std::io::stdout().lock(), color_when); |
| &mut stdout |
| } |
| }; |
| |
| self.content.write_to(writer) |
| } |
| |
| #[cfg(not(feature = "color"))] |
| pub(crate) fn print(&self) -> std::io::Result<()> { |
| // [e]println can't be used here because it panics |
| // if something went wrong. We don't want that. |
| match self.stream { |
| Stream::Stdout => { |
| let stdout = std::io::stdout(); |
| let mut stdout = stdout.lock(); |
| self.content.write_to(&mut stdout) |
| } |
| Stream::Stderr => { |
| let stderr = std::io::stderr(); |
| let mut stderr = stderr.lock(); |
| self.content.write_to(&mut stderr) |
| } |
| } |
| } |
| } |
| |
| /// Color-unaware printing. Never uses coloring. |
| impl std::fmt::Display for Colorizer { |
| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| self.content.fmt(f) |
| } |
| } |