@@ -4,7 +4,7 @@ use std::io::IsTerminal;
4
4
5
5
use anstyle:: Style ;
6
6
use anstyle_termcolor:: to_termcolor_spec;
7
- use termcolor:: { self , StandardStream , WriteColor } ;
7
+ use termcolor:: { self , BufferWriter , StandardStream , WriteColor } ;
8
8
9
9
use crate :: util:: errors:: CargoResult ;
10
10
use crate :: util:: style:: * ;
@@ -81,9 +81,15 @@ enum ShellOut {
81
81
/// A plain write object without color support
82
82
Write ( Box < dyn Write > ) ,
83
83
/// Color-enabled stdio, with information on whether color should be used
84
+ ///
85
+ /// The separate buffered fields are used for buffered writing to the
86
+ /// corresponding stream. The non-buffered fields should be used when you
87
+ /// do not want content to be buffered.
84
88
Stream {
85
89
stdout : StandardStream ,
90
+ buffered_stdout : BufferWriter ,
86
91
stderr : StandardStream ,
92
+ buffered_stderr : BufferWriter ,
87
93
stderr_tty : bool ,
88
94
color_choice : ColorChoice ,
89
95
} ,
@@ -105,10 +111,14 @@ impl Shell {
105
111
/// output.
106
112
pub fn new ( ) -> Shell {
107
113
let auto_clr = ColorChoice :: CargoAuto ;
114
+ let stdout_choice = auto_clr. to_termcolor_color_choice ( Stream :: Stdout ) ;
115
+ let stderr_choice = auto_clr. to_termcolor_color_choice ( Stream :: Stderr ) ;
108
116
Shell {
109
117
output : ShellOut :: Stream {
110
- stdout : StandardStream :: stdout ( auto_clr. to_termcolor_color_choice ( Stream :: Stdout ) ) ,
111
- stderr : StandardStream :: stderr ( auto_clr. to_termcolor_color_choice ( Stream :: Stderr ) ) ,
118
+ stdout : StandardStream :: stdout ( stdout_choice) ,
119
+ buffered_stdout : BufferWriter :: stdout ( stdout_choice) ,
120
+ stderr : StandardStream :: stderr ( stderr_choice) ,
121
+ buffered_stderr : BufferWriter :: stderr ( stderr_choice) ,
112
122
color_choice : ColorChoice :: CargoAuto ,
113
123
stderr_tty : std:: io:: stderr ( ) . is_terminal ( ) ,
114
124
} ,
@@ -287,7 +297,9 @@ impl Shell {
287
297
pub fn set_color_choice ( & mut self , color : Option < & str > ) -> CargoResult < ( ) > {
288
298
if let ShellOut :: Stream {
289
299
ref mut stdout,
300
+ ref mut buffered_stdout,
290
301
ref mut stderr,
302
+ ref mut buffered_stderr,
291
303
ref mut color_choice,
292
304
..
293
305
} = self . output
@@ -305,8 +317,12 @@ impl Shell {
305
317
) ,
306
318
} ;
307
319
* color_choice = cfg;
308
- * stdout = StandardStream :: stdout ( cfg. to_termcolor_color_choice ( Stream :: Stdout ) ) ;
309
- * stderr = StandardStream :: stderr ( cfg. to_termcolor_color_choice ( Stream :: Stderr ) ) ;
320
+ let stdout_choice = cfg. to_termcolor_color_choice ( Stream :: Stdout ) ;
321
+ let stderr_choice = cfg. to_termcolor_color_choice ( Stream :: Stderr ) ;
322
+ * stdout = StandardStream :: stdout ( stdout_choice) ;
323
+ * buffered_stdout = BufferWriter :: stdout ( stdout_choice) ;
324
+ * stderr = StandardStream :: stderr ( stderr_choice) ;
325
+ * buffered_stderr = BufferWriter :: stderr ( stderr_choice) ;
310
326
}
311
327
Ok ( ( ) )
312
328
}
@@ -410,21 +426,26 @@ impl ShellOut {
410
426
justified : bool ,
411
427
) -> CargoResult < ( ) > {
412
428
match * self {
413
- ShellOut :: Stream { ref mut stderr, .. } => {
414
- stderr. reset ( ) ?;
415
- stderr. set_color ( & to_termcolor_spec ( * style) ) ?;
429
+ ShellOut :: Stream {
430
+ ref mut buffered_stderr,
431
+ ..
432
+ } => {
433
+ let mut buffer = buffered_stderr. buffer ( ) ;
434
+ buffer. reset ( ) ?;
435
+ buffer. set_color ( & to_termcolor_spec ( * style) ) ?;
416
436
if justified {
417
- write ! ( stderr , "{:>12}" , status) ?;
437
+ write ! ( buffer , "{:>12}" , status) ?;
418
438
} else {
419
- write ! ( stderr , "{}" , status) ?;
420
- stderr . set_color ( termcolor:: ColorSpec :: new ( ) . set_bold ( true ) ) ?;
421
- write ! ( stderr , ":" ) ?;
439
+ write ! ( buffer , "{}" , status) ?;
440
+ buffer . set_color ( termcolor:: ColorSpec :: new ( ) . set_bold ( true ) ) ?;
441
+ write ! ( buffer , ":" ) ?;
422
442
}
423
- stderr . reset ( ) ?;
443
+ buffer . reset ( ) ?;
424
444
match message {
425
- Some ( message) => writeln ! ( stderr , " {}" , message) ?,
426
- None => write ! ( stderr , " " ) ?,
445
+ Some ( message) => writeln ! ( buffer , " {}" , message) ?,
446
+ None => write ! ( buffer , " " ) ?,
427
447
}
448
+ buffered_stderr. print ( & buffer) ?;
428
449
}
429
450
ShellOut :: Write ( ref mut w) => {
430
451
if justified {
@@ -444,11 +465,16 @@ impl ShellOut {
444
465
/// Write a styled fragment
445
466
fn write_stdout ( & mut self , fragment : impl fmt:: Display , color : & Style ) -> CargoResult < ( ) > {
446
467
match * self {
447
- ShellOut :: Stream { ref mut stdout, .. } => {
448
- stdout. reset ( ) ?;
449
- stdout. set_color ( & to_termcolor_spec ( * color) ) ?;
450
- write ! ( stdout, "{}" , fragment) ?;
451
- stdout. reset ( ) ?;
468
+ ShellOut :: Stream {
469
+ ref mut buffered_stdout,
470
+ ..
471
+ } => {
472
+ let mut buffer = buffered_stdout. buffer ( ) ;
473
+ buffer. reset ( ) ?;
474
+ buffer. set_color ( & to_termcolor_spec ( * color) ) ?;
475
+ write ! ( buffer, "{}" , fragment) ?;
476
+ buffer. reset ( ) ?;
477
+ buffered_stdout. print ( & buffer) ?;
452
478
}
453
479
ShellOut :: Write ( ref mut w) => {
454
480
write ! ( w, "{}" , fragment) ?;
@@ -460,11 +486,16 @@ impl ShellOut {
460
486
/// Write a styled fragment
461
487
fn write_stderr ( & mut self , fragment : impl fmt:: Display , color : & Style ) -> CargoResult < ( ) > {
462
488
match * self {
463
- ShellOut :: Stream { ref mut stderr, .. } => {
464
- stderr. reset ( ) ?;
465
- stderr. set_color ( & to_termcolor_spec ( * color) ) ?;
466
- write ! ( stderr, "{}" , fragment) ?;
467
- stderr. reset ( ) ?;
489
+ ShellOut :: Stream {
490
+ ref mut buffered_stderr,
491
+ ..
492
+ } => {
493
+ let mut buffer = buffered_stderr. buffer ( ) ;
494
+ buffer. reset ( ) ?;
495
+ buffer. set_color ( & to_termcolor_spec ( * color) ) ?;
496
+ write ! ( buffer, "{}" , fragment) ?;
497
+ buffer. reset ( ) ?;
498
+ buffered_stderr. print ( & buffer) ?;
468
499
}
469
500
ShellOut :: Write ( ref mut w) => {
470
501
write ! ( w, "{}" , fragment) ?;
0 commit comments