1+ use diffy;
12use std:: env;
2- use std:: fs :: OpenOptions ;
3+ use std:: fmt :: Debug ;
34use std:: io;
45use std:: path:: { Path , PathBuf } ;
56use std:: process:: Command ;
@@ -26,6 +27,12 @@ pub enum CheckDiffError {
2627 IO ( std:: io:: Error ) ,
2728}
2829
30+ impl Debug for CheckDiffError {
31+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
32+ f. debug_struct ( "CheckDiffError" ) . finish ( )
33+ }
34+ }
35+
2936impl From < io:: Error > for CheckDiffError {
3037 fn from ( error : io:: Error ) -> Self {
3138 CheckDiffError :: IO ( error)
@@ -59,7 +66,6 @@ impl From<io::Error> for GitError {
5966}
6067
6168// will be used in future PRs, just added to make the compiler happy
62- #[ allow( dead_code) ]
6369pub struct CheckDiffRunners {
6470 pub feature_runner : RustfmtRunner ,
6571 pub src_runner : RustfmtRunner ,
@@ -70,6 +76,21 @@ pub struct RustfmtRunner {
7076 binary_path : PathBuf ,
7177}
7278
79+ impl CheckDiffRunners {
80+ /// Creates a diff generated by running the source and feature binaries on the same file path
81+ pub fn create_diff (
82+ & self ,
83+ path : & Path ,
84+ additional_configs : & Option < Vec < String > > ,
85+ ) -> Result < String , CheckDiffError > {
86+ let code = std:: fs:: read_to_string ( path) ?;
87+ let src_format = self . src_runner . format_code ( & code, additional_configs) ?;
88+ let feature_format = self . feature_runner . format_code ( & code, additional_configs) ?;
89+ let diff = diffy:: create_patch ( src_format. as_str ( ) , feature_format. as_str ( ) ) ;
90+ Ok ( format ! ( "{diff}" ) )
91+ }
92+ }
93+
7394impl RustfmtRunner {
7495 fn get_binary_version ( & self ) -> Result < String , CheckDiffError > {
7596 let Ok ( command) = Command :: new ( & self . binary_path )
@@ -86,19 +107,18 @@ impl RustfmtRunner {
86107 return Ok ( binary_version. to_string ( ) ) ;
87108 }
88109
89- // Run rusfmt with the --check flag to see if a diff is produced.
110+ // Run rusfmt with the --check flag to see if a diff is produced. Runs on the code specified
90111 //
91112 // Parameters:
92113 // binary_path: Path to a rustfmt binary
93- // output_path: Output file path for the diff
114+ // code: Code to run the binary on
94115 // config: Any additional configuration options to pass to rustfmt
95116 //
96- #[ allow( dead_code) ]
97- fn create_diff (
117+ fn format_code < ' a > (
98118 & self ,
99- output_path : & Path ,
100- config : Option < Vec < String > > ,
101- ) -> Result < ( ) , CheckDiffError > {
119+ code : & ' a str ,
120+ config : & Option < Vec < String > > ,
121+ ) -> Result < String , CheckDiffError > {
102122 let config_arg: String = match config {
103123 Some ( configs) => {
104124 let mut result = String :: new ( ) ;
@@ -117,33 +137,18 @@ impl RustfmtRunner {
117137 config_arg. as_str( )
118138 ) ;
119139
120- // walks the "." directory and finds all files with .rs extensions
121- for entry in WalkDir :: new ( "." ) . into_iter ( ) . filter_map ( |e| e. ok ( ) ) {
122- let path = entry. path ( ) ;
123- if path. is_file ( ) && path. extension ( ) . map_or ( false , |ext| ext == "rs" ) {
124- let file = OpenOptions :: new ( )
125- . write ( true )
126- . append ( true )
127- . open ( output_path) ?;
128- let Ok ( _) = Command :: new ( & self . binary_path )
129- . env ( "LD_LIBRARY_PATH" , & self . ld_library_path )
130- . args ( [
131- "--unstable-features" ,
132- "--skip-children" ,
133- "--check" ,
134- "--color=always" ,
135- config. as_str ( ) ,
136- ] )
137- . stdout ( file)
138- . output ( )
139- else {
140- return Err ( CheckDiffError :: FailedWritingToFile (
141- "Failed to write to file" ,
142- ) ) ;
143- } ;
144- }
145- }
146- Ok ( ( ) )
140+ let output = Command :: new ( & self . binary_path )
141+ . env ( "LD_LIBRARY_PATH" , & self . ld_library_path )
142+ . args ( [
143+ "--unstable-features" ,
144+ "--skip-children" ,
145+ "--emit=stdout" ,
146+ config. as_str ( ) ,
147+ code,
148+ ] )
149+ . output ( ) ?;
150+
151+ Ok ( std:: str:: from_utf8 ( & output. stdout ) ?. to_string ( ) )
147152 }
148153}
149154
@@ -335,3 +340,25 @@ pub fn compile_rustfmt(
335340 feature_runner,
336341 } ) ;
337342}
343+
344+ pub fn check_diff ( config : Option < Vec < String > > , runners : CheckDiffRunners ) -> i32 {
345+ let mut errors = 0 ;
346+ for entry in WalkDir :: new ( "." ) . into_iter ( ) . filter_map ( |e| e. ok ( ) ) {
347+ let path = entry. path ( ) ;
348+ if path. is_file ( ) && path. extension ( ) . map_or ( false , |ext| ext == "rs" ) {
349+ match runners. create_diff ( path, & config) {
350+ Ok ( diff) => {
351+ if !diff. is_empty ( ) {
352+ eprint ! ( "diff" ) ;
353+ errors += 1 ;
354+ }
355+ }
356+ Err ( e) => {
357+ eprintln ! ( "Error creating diff for {:?}: {:?}" , path. display( ) , e) ;
358+ errors += 1 ;
359+ }
360+ }
361+ }
362+ }
363+ return errors;
364+ }
0 commit comments