@@ -12,7 +12,7 @@ use crate::line_range::{LineRanges, RangeCheckResult};
1212use crate :: output:: OutputType ;
1313#[ cfg( feature = "paging" ) ]
1414use crate :: paging:: PagingMode ;
15- use crate :: printer:: { InteractivePrinter , Printer , SimplePrinter } ;
15+ use crate :: printer:: { InteractivePrinter , OutputHandle , Printer , SimplePrinter } ;
1616
1717use clircle:: { Clircle , Identifier } ;
1818
@@ -26,13 +26,18 @@ impl<'b> Controller<'b> {
2626 Controller { config, assets }
2727 }
2828
29- pub fn run ( & self , inputs : Vec < Input > ) -> Result < bool > {
30- self . run_with_error_handler ( inputs, default_error_handler)
29+ pub fn run (
30+ & self ,
31+ inputs : Vec < Input > ,
32+ output_buffer : Option < & mut dyn std:: fmt:: Write > ,
33+ ) -> Result < bool > {
34+ self . run_with_error_handler ( inputs, output_buffer, default_error_handler)
3135 }
3236
3337 pub fn run_with_error_handler (
3438 & self ,
3539 inputs : Vec < Input > ,
40+ output_buffer : Option < & mut dyn std:: fmt:: Write > ,
3641 handle_error : impl Fn ( & Error , & mut dyn Write ) ,
3742 ) -> Result < bool > {
3843 let mut output_type;
@@ -74,24 +79,34 @@ impl<'b> Controller<'b> {
7479 clircle:: Identifier :: stdout ( )
7580 } ;
7681
77- let writer = output_type. handle ( ) ?;
82+ let mut writer = match output_buffer {
83+ Some ( buf) => OutputHandle :: FmtWrite ( buf) ,
84+ None => OutputHandle :: IoWrite ( output_type. handle ( ) ?) ,
85+ } ;
7886 let mut no_errors: bool = true ;
7987 let stderr = io:: stderr ( ) ;
8088
8189 for ( index, input) in inputs. into_iter ( ) . enumerate ( ) {
8290 let identifier = stdout_identifier. as_ref ( ) ;
8391 let is_first = index == 0 ;
8492 let result = if input. is_stdin ( ) {
85- self . print_input ( input, writer, io:: stdin ( ) . lock ( ) , identifier, is_first)
93+ self . print_input ( input, & mut writer, io:: stdin ( ) . lock ( ) , identifier, is_first)
8694 } else {
8795 // Use dummy stdin since stdin is actually not used (#1902)
88- self . print_input ( input, writer, io:: empty ( ) , identifier, is_first)
96+ self . print_input ( input, & mut writer, io:: empty ( ) , identifier, is_first)
8997 } ;
9098 if let Err ( error) = result {
91- if attached_to_pager {
92- handle_error ( & error, writer) ;
93- } else {
94- handle_error ( & error, & mut stderr. lock ( ) ) ;
99+ match writer {
100+ // It doesn't make much sense to send errors straight to stderr if the user
101+ // provided their own buffer, so we just return it.
102+ OutputHandle :: FmtWrite ( _) => return Err ( error) ,
103+ OutputHandle :: IoWrite ( ref mut writer) => {
104+ if attached_to_pager {
105+ handle_error ( & error, writer) ;
106+ } else {
107+ handle_error ( & error, & mut stderr. lock ( ) ) ;
108+ }
109+ }
95110 }
96111 no_errors = false ;
97112 }
@@ -103,7 +118,7 @@ impl<'b> Controller<'b> {
103118 fn print_input < R : BufRead > (
104119 & self ,
105120 input : Input ,
106- writer : & mut dyn Write ,
121+ writer : & mut OutputHandle ,
107122 stdin : R ,
108123 stdout_identifier : Option < & Identifier > ,
109124 is_first : bool ,
@@ -164,7 +179,7 @@ impl<'b> Controller<'b> {
164179 fn print_file (
165180 & self ,
166181 printer : & mut dyn Printer ,
167- writer : & mut dyn Write ,
182+ writer : & mut OutputHandle ,
168183 input : & mut OpenedInput ,
169184 add_header_padding : bool ,
170185 #[ cfg( feature = "git" ) ] line_changes : & Option < LineChanges > ,
@@ -202,7 +217,7 @@ impl<'b> Controller<'b> {
202217 fn print_file_ranges (
203218 & self ,
204219 printer : & mut dyn Printer ,
205- writer : & mut dyn Write ,
220+ writer : & mut OutputHandle ,
206221 reader : & mut InputReader ,
207222 line_ranges : & LineRanges ,
208223 ) -> Result < ( ) > {
0 commit comments