1mod buffer;
2mod target;
3
4use std::{io, mem, sync::Mutex};
5
6use buffer::BufferWriter;
7
8pub(crate) use buffer::Buffer;
9
10pub use target::Target;
11
12#[allow(clippy::exhaustive_enums)] #[derive(#[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::clone::Clone for WriteStyle {
#[inline]
fn clone(&self) -> WriteStyle { *self }
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::marker::Copy for WriteStyle { }Copy, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::fmt::Debug for WriteStyle {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
WriteStyle::Auto => "Auto",
WriteStyle::Always => "Always",
WriteStyle::Never => "Never",
})
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::cmp::Eq for WriteStyle {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {}
}Eq, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::hash::Hash for WriteStyle {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::cmp::PartialEq for WriteStyle {
#[inline]
fn eq(&self, other: &WriteStyle) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::default::Default for WriteStyle {
#[inline]
fn default() -> WriteStyle { Self::Auto }
}Default)]
15pub enum WriteStyle {
16 #[default]
18 Auto,
19 Always,
21 Never,
23}
24
25#[cfg(feature = "color")]
26impl From<anstream::ColorChoice> for WriteStyle {
27 fn from(choice: anstream::ColorChoice) -> Self {
28 match choice {
29 anstream::ColorChoice::Auto => Self::Auto,
30 anstream::ColorChoice::Always => Self::Always,
31 anstream::ColorChoice::AlwaysAnsi => Self::Always,
32 anstream::ColorChoice::Never => Self::Never,
33 }
34 }
35}
36
37#[cfg(feature = "color")]
38impl From<WriteStyle> for anstream::ColorChoice {
39 fn from(choice: WriteStyle) -> Self {
40 match choice {
41 WriteStyle::Auto => anstream::ColorChoice::Auto,
42 WriteStyle::Always => anstream::ColorChoice::Always,
43 WriteStyle::Never => anstream::ColorChoice::Never,
44 }
45 }
46}
47
48#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Writer {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "Writer",
"inner", &&self.inner)
}
}Debug)]
50pub(crate) struct Writer {
51 inner: BufferWriter,
52}
53
54impl Writer {
55 pub(crate) fn write_style(&self) -> WriteStyle {
56 self.inner.write_style()
57 }
58
59 pub(crate) fn buffer(&self) -> Buffer {
60 self.inner.buffer()
61 }
62
63 pub(crate) fn print(&self, buf: &Buffer) -> io::Result<()> {
64 self.inner.print(buf)
65 }
66}
67
68#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Builder {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "Builder",
"target", &self.target, "write_style", &self.write_style,
"is_test", &self.is_test, "built", &&self.built)
}
}Debug)]
72pub(crate) struct Builder {
73 target: Target,
74 write_style: WriteStyle,
75 is_test: bool,
76 built: bool,
77}
78
79impl Builder {
80 pub(crate) fn new() -> Self {
82 Builder {
83 target: Default::default(),
84 write_style: Default::default(),
85 is_test: false,
86 built: false,
87 }
88 }
89
90 pub(crate) fn target(&mut self, target: Target) -> &mut Self {
92 self.target = target;
93 self
94 }
95
96 pub(crate) fn parse_write_style(&mut self, write_style: &str) -> &mut Self {
102 self.write_style(parse_write_style(write_style))
103 }
104
105 pub(crate) fn write_style(&mut self, write_style: WriteStyle) -> &mut Self {
107 self.write_style = write_style;
108 self
109 }
110
111 #[allow(clippy::wrong_self_convention)]
113 pub(crate) fn is_test(&mut self, is_test: bool) -> &mut Self {
114 self.is_test = is_test;
115 self
116 }
117
118 pub(crate) fn build(&mut self) -> Writer {
120 if !!self.built {
{
::core::panicking::panic_fmt(format_args!("attempt to re-use consumed builder"));
}
};assert!(!self.built, "attempt to re-use consumed builder");
121 self.built = true;
122
123 let color_choice = self.write_style;
124 #[cfg(feature = "auto-color")]
125 let color_choice = if color_choice == WriteStyle::Auto {
126 match &self.target {
127 Target::Stdout => anstream::AutoStream::choice(&io::stdout()).into(),
128 Target::Stderr => anstream::AutoStream::choice(&io::stderr()).into(),
129 Target::Pipe(_) => color_choice,
130 }
131 } else {
132 color_choice
133 };
134 let color_choice = if color_choice == WriteStyle::Auto {
135 WriteStyle::Never
136 } else {
137 color_choice
138 };
139
140 let writer = match mem::take(&mut self.target) {
141 Target::Stdout => BufferWriter::stdout(self.is_test, color_choice),
142 Target::Stderr => BufferWriter::stderr(self.is_test, color_choice),
143 Target::Pipe(pipe) => BufferWriter::pipe(Box::new(Mutex::new(pipe)), color_choice),
144 };
145
146 Writer { inner: writer }
147 }
148}
149
150impl Default for Builder {
151 fn default() -> Self {
152 Builder::new()
153 }
154}
155
156fn parse_write_style(spec: &str) -> WriteStyle {
157 match spec {
158 "auto" => WriteStyle::Auto,
159 "always" => WriteStyle::Always,
160 "never" => WriteStyle::Never,
161 _ => Default::default(),
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn parse_write_style_valid() {
171 let inputs = vec![
172 ("auto", WriteStyle::Auto),
173 ("always", WriteStyle::Always),
174 ("never", WriteStyle::Never),
175 ];
176
177 for (input, expected) in inputs {
178 assert_eq!(expected, parse_write_style(input));
179 }
180 }
181
182 #[test]
183 fn parse_write_style_invalid() {
184 let inputs = vec!["", "true", "false", "NEVER!!"];
185
186 for input in inputs {
187 assert_eq!(WriteStyle::Auto, parse_write_style(input));
188 }
189 }
190}