@@ -4,7 +4,7 @@ use std::io::IsTerminal;
44
55use anstyle:: Style ;
66use anstyle_termcolor:: to_termcolor_spec;
7- use termcolor:: { self , StandardStream , WriteColor } ;
7+ use termcolor:: { self , BufferWriter , StandardStream , WriteColor } ;
88
99use crate :: util:: errors:: CargoResult ;
1010use crate :: util:: style:: * ;
@@ -81,9 +81,15 @@ enum ShellOut {
8181 /// A plain write object without color support
8282 Write ( Box < dyn Write > ) ,
8383 /// 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.
8488 Stream {
8589 stdout : StandardStream ,
90+ buffered_stdout : BufferWriter ,
8691 stderr : StandardStream ,
92+ buffered_stderr : BufferWriter ,
8793 stderr_tty : bool ,
8894 color_choice : ColorChoice ,
8995 } ,
@@ -105,10 +111,14 @@ impl Shell {
105111 /// output.
106112 pub fn new ( ) -> Shell {
107113 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 ) ;
108116 Shell {
109117 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) ,
112122 color_choice : ColorChoice :: CargoAuto ,
113123 stderr_tty : std:: io:: stderr ( ) . is_terminal ( ) ,
114124 } ,
@@ -287,7 +297,9 @@ impl Shell {
287297 pub fn set_color_choice ( & mut self , color : Option < & str > ) -> CargoResult < ( ) > {
288298 if let ShellOut :: Stream {
289299 ref mut stdout,
300+ ref mut buffered_stdout,
290301 ref mut stderr,
302+ ref mut buffered_stderr,
291303 ref mut color_choice,
292304 ..
293305 } = self . output
@@ -305,8 +317,12 @@ impl Shell {
305317 ) ,
306318 } ;
307319 * 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) ;
310326 }
311327 Ok ( ( ) )
312328 }
@@ -410,21 +426,26 @@ impl ShellOut {
410426 justified : bool ,
411427 ) -> CargoResult < ( ) > {
412428 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) ) ?;
416436 if justified {
417- write ! ( stderr , "{:>12}" , status) ?;
437+ write ! ( buffer , "{:>12}" , status) ?;
418438 } 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 , ":" ) ?;
422442 }
423- stderr . reset ( ) ?;
443+ buffer . reset ( ) ?;
424444 match message {
425- Some ( message) => writeln ! ( stderr , " {}" , message) ?,
426- None => write ! ( stderr , " " ) ?,
445+ Some ( message) => writeln ! ( buffer , " {}" , message) ?,
446+ None => write ! ( buffer , " " ) ?,
427447 }
448+ buffered_stderr. print ( & buffer) ?;
428449 }
429450 ShellOut :: Write ( ref mut w) => {
430451 if justified {
@@ -444,11 +465,16 @@ impl ShellOut {
444465 /// Write a styled fragment
445466 fn write_stdout ( & mut self , fragment : impl fmt:: Display , color : & Style ) -> CargoResult < ( ) > {
446467 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) ?;
452478 }
453479 ShellOut :: Write ( ref mut w) => {
454480 write ! ( w, "{}" , fragment) ?;
@@ -460,11 +486,16 @@ impl ShellOut {
460486 /// Write a styled fragment
461487 fn write_stderr ( & mut self , fragment : impl fmt:: Display , color : & Style ) -> CargoResult < ( ) > {
462488 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) ?;
468499 }
469500 ShellOut :: Write ( ref mut w) => {
470501 write ! ( w, "{}" , fragment) ?;
0 commit comments