1
1
use std:: borrow:: Cow ;
2
2
use std:: cell:: RefCell ;
3
3
use std:: fmt;
4
- use std:: io:: { self , Write } ;
5
4
use std:: rc:: Rc ;
6
- use std:: sync:: Mutex ;
7
5
8
- use log:: Level ;
9
- use termcolor:: { self , ColorChoice , ColorSpec , WriteColor } ;
10
-
11
- use crate :: fmt:: { Formatter , WritableTarget , WriteStyle } ;
12
-
13
- pub ( in crate :: fmt:: writer) mod glob {
14
- pub use super :: * ;
15
- }
16
-
17
- impl Formatter {
18
- /// Begin a new [`Style`].
19
- ///
20
- /// # Examples
21
- ///
22
- /// Create a bold, red colored style and use it to print the log level:
23
- ///
24
- /// ```
25
- /// use std::io::Write;
26
- /// use env_logger::fmt::Color;
27
- ///
28
- /// let mut builder = env_logger::Builder::new();
29
- ///
30
- /// builder.format(|buf, record| {
31
- /// let mut level_style = buf.style();
32
- ///
33
- /// level_style.set_color(Color::Red).set_bold(true);
34
- ///
35
- /// writeln!(buf, "{}: {}",
36
- /// level_style.value(record.level()),
37
- /// record.args())
38
- /// });
39
- /// ```
40
- ///
41
- /// [`Style`]: struct.Style.html
42
- pub fn style ( & self ) -> Style {
43
- Style {
44
- buf : self . buf . clone ( ) ,
45
- spec : ColorSpec :: new ( ) ,
46
- }
47
- }
48
-
49
- /// Get the default [`Style`] for the given level.
50
- ///
51
- /// The style can be used to print other values besides the level.
52
- pub fn default_level_style ( & self , level : Level ) -> Style {
53
- let mut level_style = self . style ( ) ;
54
- match level {
55
- Level :: Trace => level_style. set_color ( Color :: Cyan ) ,
56
- Level :: Debug => level_style. set_color ( Color :: Blue ) ,
57
- Level :: Info => level_style. set_color ( Color :: Green ) ,
58
- Level :: Warn => level_style. set_color ( Color :: Yellow ) ,
59
- Level :: Error => level_style. set_color ( Color :: Red ) . set_bold ( true ) ,
60
- } ;
61
- level_style
62
- }
63
-
64
- /// Get a printable [`Style`] for the given level.
65
- ///
66
- /// The style can only be used to print the level.
67
- pub fn default_styled_level ( & self , level : Level ) -> StyledValue < ' static , Level > {
68
- self . default_level_style ( level) . into_value ( level)
69
- }
70
- }
71
-
72
- pub ( in crate :: fmt:: writer) struct BufferWriter {
73
- inner : termcolor:: BufferWriter ,
74
- uncolored_target : Option < WritableTarget > ,
75
- }
76
-
77
- pub ( in crate :: fmt) struct Buffer {
78
- inner : termcolor:: Buffer ,
79
- has_uncolored_target : bool ,
80
- }
81
-
82
- impl BufferWriter {
83
- pub ( in crate :: fmt:: writer) fn stderr ( is_test : bool , write_style : WriteStyle ) -> Self {
84
- BufferWriter {
85
- inner : termcolor:: BufferWriter :: stderr ( write_style. into_color_choice ( ) ) ,
86
- uncolored_target : if is_test {
87
- Some ( WritableTarget :: Stderr )
88
- } else {
89
- None
90
- } ,
91
- }
92
- }
93
-
94
- pub ( in crate :: fmt:: writer) fn stdout ( is_test : bool , write_style : WriteStyle ) -> Self {
95
- BufferWriter {
96
- inner : termcolor:: BufferWriter :: stdout ( write_style. into_color_choice ( ) ) ,
97
- uncolored_target : if is_test {
98
- Some ( WritableTarget :: Stdout )
99
- } else {
100
- None
101
- } ,
102
- }
103
- }
104
-
105
- pub ( in crate :: fmt:: writer) fn pipe (
106
- write_style : WriteStyle ,
107
- pipe : Box < Mutex < dyn io:: Write + Send + ' static > > ,
108
- ) -> Self {
109
- BufferWriter {
110
- // The inner Buffer is never printed from, but it is still needed to handle coloring and other formatting
111
- inner : termcolor:: BufferWriter :: stderr ( write_style. into_color_choice ( ) ) ,
112
- uncolored_target : Some ( WritableTarget :: Pipe ( pipe) ) ,
113
- }
114
- }
115
-
116
- pub ( in crate :: fmt:: writer) fn buffer ( & self ) -> Buffer {
117
- Buffer {
118
- inner : self . inner . buffer ( ) ,
119
- has_uncolored_target : self . uncolored_target . is_some ( ) ,
120
- }
121
- }
122
-
123
- pub ( in crate :: fmt:: writer) fn print ( & self , buf : & Buffer ) -> io:: Result < ( ) > {
124
- if let Some ( target) = & self . uncolored_target {
125
- // This impl uses the `eprint` and `print` macros
126
- // instead of `termcolor`'s buffer.
127
- // This is so their output can be captured by `cargo test`
128
- let log = String :: from_utf8_lossy ( buf. bytes ( ) ) ;
129
-
130
- match target {
131
- WritableTarget :: Stderr => eprint ! ( "{}" , log) ,
132
- WritableTarget :: Stdout => print ! ( "{}" , log) ,
133
- WritableTarget :: Pipe ( pipe) => write ! ( pipe. lock( ) . unwrap( ) , "{}" , log) ?,
134
- }
135
-
136
- Ok ( ( ) )
137
- } else {
138
- self . inner . print ( & buf. inner )
139
- }
140
- }
141
- }
142
-
143
- impl Buffer {
144
- pub ( in crate :: fmt) fn clear ( & mut self ) {
145
- self . inner . clear ( )
146
- }
147
-
148
- pub ( in crate :: fmt) fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
149
- self . inner . write ( buf)
150
- }
151
-
152
- pub ( in crate :: fmt) fn flush ( & mut self ) -> io:: Result < ( ) > {
153
- self . inner . flush ( )
154
- }
155
-
156
- pub ( in crate :: fmt) fn bytes ( & self ) -> & [ u8 ] {
157
- self . inner . as_slice ( )
158
- }
159
-
160
- fn set_color ( & mut self , spec : & ColorSpec ) -> io:: Result < ( ) > {
161
- // Ignore styles for test captured logs because they can't be printed
162
- if !self . has_uncolored_target {
163
- self . inner . set_color ( spec)
164
- } else {
165
- Ok ( ( ) )
166
- }
167
- }
168
-
169
- fn reset ( & mut self ) -> io:: Result < ( ) > {
170
- // Ignore styles for test captured logs because they can't be printed
171
- if !self . has_uncolored_target {
172
- self . inner . reset ( )
173
- } else {
174
- Ok ( ( ) )
175
- }
176
- }
177
- }
178
-
179
- impl WriteStyle {
180
- fn into_color_choice ( self ) -> ColorChoice {
181
- match self {
182
- WriteStyle :: Always => ColorChoice :: Always ,
183
- WriteStyle :: Auto => ColorChoice :: Auto ,
184
- WriteStyle :: Never => ColorChoice :: Never ,
185
- }
186
- }
187
- }
6
+ use super :: Buffer ;
188
7
189
8
/// A set of styles to apply to the terminal output.
190
9
///
@@ -240,18 +59,8 @@ impl WriteStyle {
240
59
/// [`value`]: #method.value
241
60
#[ derive( Clone ) ]
242
61
pub struct Style {
243
- buf : Rc < RefCell < Buffer > > ,
244
- spec : ColorSpec ,
245
- }
246
-
247
- /// A value that can be printed using the given styles.
248
- ///
249
- /// It is the result of calling [`Style::value`].
250
- ///
251
- /// [`Style::value`]: struct.Style.html#method.value
252
- pub struct StyledValue < ' a , T > {
253
- style : Cow < ' a , Style > ,
254
- value : T ,
62
+ pub ( in crate :: fmt) buf : Rc < RefCell < Buffer > > ,
63
+ pub ( in crate :: fmt) spec : termcolor:: ColorSpec ,
255
64
}
256
65
257
66
impl Style {
@@ -426,6 +235,22 @@ impl Style {
426
235
}
427
236
}
428
237
238
+ impl fmt:: Debug for Style {
239
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
240
+ f. debug_struct ( "Style" ) . field ( "spec" , & self . spec ) . finish ( )
241
+ }
242
+ }
243
+
244
+ /// A value that can be printed using the given styles.
245
+ ///
246
+ /// It is the result of calling [`Style::value`].
247
+ ///
248
+ /// [`Style::value`]: struct.Style.html#method.value
249
+ pub struct StyledValue < ' a , T > {
250
+ style : Cow < ' a , Style > ,
251
+ value : T ,
252
+ }
253
+
429
254
impl < ' a , T > StyledValue < ' a , T > {
430
255
fn write_fmt < F > ( & self , f : F ) -> fmt:: Result
431
256
where
@@ -445,12 +270,6 @@ impl<'a, T> StyledValue<'a, T> {
445
270
}
446
271
}
447
272
448
- impl fmt:: Debug for Style {
449
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
450
- f. debug_struct ( "Style" ) . field ( "spec" , & self . spec ) . finish ( )
451
- }
452
- }
453
-
454
273
macro_rules! impl_styled_value_fmt {
455
274
( $( $fmt_trait: path) ,* ) => {
456
275
$(
0 commit comments