1use std::io::{self, IsTerminal};
2
3use termcolor::HyperlinkSpec;
4
5#[derive(Debug)]
7pub struct StandardStream(StandardStreamKind);
8
9pub fn stdout(color_choice: termcolor::ColorChoice) -> StandardStream {
24 if std::io::stdout().is_terminal() {
25 stdout_buffered_line(color_choice)
26 } else {
27 stdout_buffered_block(color_choice)
28 }
29}
30
31pub fn stdout_buffered_line(
40 color_choice: termcolor::ColorChoice,
41) -> StandardStream {
42 let out = termcolor::StandardStream::stdout(color_choice);
43 StandardStream(StandardStreamKind::LineBuffered(out))
44}
45
46pub fn stdout_buffered_block(
55 color_choice: termcolor::ColorChoice,
56) -> StandardStream {
57 let out = termcolor::BufferedStandardStream::stdout(color_choice);
58 StandardStream(StandardStreamKind::BlockBuffered(out))
59}
60
61#[derive(Debug)]
62enum StandardStreamKind {
63 LineBuffered(termcolor::StandardStream),
64 BlockBuffered(termcolor::BufferedStandardStream),
65}
66
67impl io::Write for StandardStream {
68 #[inline]
69 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
70 use self::StandardStreamKind::*;
71
72 match self.0 {
73 LineBuffered(ref mut w) => w.write(buf),
74 BlockBuffered(ref mut w) => w.write(buf),
75 }
76 }
77
78 #[inline]
79 fn flush(&mut self) -> io::Result<()> {
80 use self::StandardStreamKind::*;
81
82 match self.0 {
83 LineBuffered(ref mut w) => w.flush(),
84 BlockBuffered(ref mut w) => w.flush(),
85 }
86 }
87}
88
89impl termcolor::WriteColor for StandardStream {
90 #[inline]
91 fn supports_color(&self) -> bool {
92 use self::StandardStreamKind::*;
93
94 match self.0 {
95 LineBuffered(ref w) => w.supports_color(),
96 BlockBuffered(ref w) => w.supports_color(),
97 }
98 }
99
100 #[inline]
101 fn supports_hyperlinks(&self) -> bool {
102 use self::StandardStreamKind::*;
103
104 match self.0 {
105 LineBuffered(ref w) => w.supports_hyperlinks(),
106 BlockBuffered(ref w) => w.supports_hyperlinks(),
107 }
108 }
109
110 #[inline]
111 fn set_color(&mut self, spec: &termcolor::ColorSpec) -> io::Result<()> {
112 use self::StandardStreamKind::*;
113
114 match self.0 {
115 LineBuffered(ref mut w) => w.set_color(spec),
116 BlockBuffered(ref mut w) => w.set_color(spec),
117 }
118 }
119
120 #[inline]
121 fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
122 use self::StandardStreamKind::*;
123
124 match self.0 {
125 LineBuffered(ref mut w) => w.set_hyperlink(link),
126 BlockBuffered(ref mut w) => w.set_hyperlink(link),
127 }
128 }
129
130 #[inline]
131 fn reset(&mut self) -> io::Result<()> {
132 use self::StandardStreamKind::*;
133
134 match self.0 {
135 LineBuffered(ref mut w) => w.reset(),
136 BlockBuffered(ref mut w) => w.reset(),
137 }
138 }
139
140 #[inline]
141 fn is_synchronous(&self) -> bool {
142 use self::StandardStreamKind::*;
143
144 match self.0 {
145 LineBuffered(ref w) => w.is_synchronous(),
146 BlockBuffered(ref w) => w.is_synchronous(),
147 }
148 }
149}