1 use crate::builder::StyledStr; 2 use crate::util::color::ColorChoice; 3 4 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 5 pub(crate) enum Stream { 6 Stdout, 7 Stderr, 8 } 9 10 #[derive(Clone, Debug)] 11 pub(crate) struct Colorizer { 12 stream: Stream, 13 #[allow(unused)] 14 color_when: ColorChoice, 15 content: StyledStr, 16 } 17 18 impl Colorizer { new(stream: Stream, color_when: ColorChoice) -> Self19 pub(crate) fn new(stream: Stream, color_when: ColorChoice) -> Self { 20 Colorizer { 21 stream, 22 color_when, 23 content: Default::default(), 24 } 25 } 26 with_content(mut self, content: StyledStr) -> Self27 pub(crate) fn with_content(mut self, content: StyledStr) -> Self { 28 self.content = content; 29 self 30 } 31 } 32 33 /// Printing methods. 34 impl Colorizer { 35 #[cfg(feature = "color")] print(&self) -> std::io::Result<()>36 pub(crate) fn print(&self) -> std::io::Result<()> { 37 let color_when = match self.color_when { 38 ColorChoice::Always => anstream::ColorChoice::Always, 39 ColorChoice::Auto => anstream::ColorChoice::Auto, 40 ColorChoice::Never => anstream::ColorChoice::Never, 41 }; 42 43 let mut stdout; 44 let mut stderr; 45 let writer: &mut dyn std::io::Write = match self.stream { 46 Stream::Stderr => { 47 stderr = anstream::AutoStream::new(std::io::stderr().lock(), color_when); 48 &mut stderr 49 } 50 Stream::Stdout => { 51 stdout = anstream::AutoStream::new(std::io::stdout().lock(), color_when); 52 &mut stdout 53 } 54 }; 55 56 self.content.write_to(writer) 57 } 58 59 #[cfg(not(feature = "color"))] print(&self) -> std::io::Result<()>60 pub(crate) fn print(&self) -> std::io::Result<()> { 61 // [e]println can't be used here because it panics 62 // if something went wrong. We don't want that. 63 match self.stream { 64 Stream::Stdout => { 65 let stdout = std::io::stdout(); 66 let mut stdout = stdout.lock(); 67 self.content.write_to(&mut stdout) 68 } 69 Stream::Stderr => { 70 let stderr = std::io::stderr(); 71 let mut stderr = stderr.lock(); 72 self.content.write_to(&mut stderr) 73 } 74 } 75 } 76 } 77 78 /// Color-unaware printing. Never uses coloring. 79 impl std::fmt::Display for Colorizer { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result80 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 81 self.content.fmt(f) 82 } 83 } 84