1
1
use env_logger;
2
- # [ macro_use ]
3
- extern crate failure ;
2
+ use failure :: { err_msg , format_err , Error as FailureError , Fail } ;
3
+ use io :: Error as IoError ;
4
4
5
5
use rustfmt_nightly as rustfmt;
6
6
@@ -10,12 +10,10 @@ use std::io::{self, stdout, Read, Write};
10
10
use std:: path:: { Path , PathBuf } ;
11
11
use std:: str:: FromStr ;
12
12
13
- use failure:: err_msg;
14
-
15
13
use getopts:: { Matches , Options } ;
16
14
17
15
use crate :: rustfmt:: {
18
- load_config, CliOptions , Color , Config , Edition , EmitMode , ErrorKind , FileLines , FileName ,
16
+ load_config, CliOptions , Color , Config , Edition , EmitMode , FileLines , FileName ,
19
17
FormatReportFormatterBuilder , Input , Session , Verbosity ,
20
18
} ;
21
19
@@ -49,20 +47,37 @@ enum Operation {
49
47
} ,
50
48
/// Print the help message.
51
49
Help ( HelpOp ) ,
52
- // Print version information
50
+ /// Print version information
53
51
Version ,
54
52
/// Output default config to a file, or stdout if None
55
- ConfigOutputDefault {
56
- path : Option < String > ,
57
- } ,
53
+ ConfigOutputDefault { path : Option < String > } ,
58
54
/// Output current config (as if formatting to a file) to stdout
59
- ConfigOutputCurrent {
60
- path : Option < String > ,
61
- } ,
55
+ ConfigOutputCurrent { path : Option < String > } ,
62
56
/// No file specified, read from stdin
63
- Stdin {
64
- input : String ,
65
- } ,
57
+ Stdin { input : String } ,
58
+ }
59
+
60
+ /// Rustfmt operations errors.
61
+ #[ derive( Fail , Debug ) ]
62
+ pub enum OperationError {
63
+ /// An unknown help topic was requested.
64
+ #[ fail( display = "Unknown help topic: `{}`." , _0) ]
65
+ UnknownHelpTopic ( String ) ,
66
+ /// An unknown print-config option was requested.
67
+ #[ fail( display = "Unknown print-config option: `{}`." , _0) ]
68
+ UnknownPrintConfigTopic ( String ) ,
69
+ /// Attempt to generate a minimal config from standard input.
70
+ #[ fail( display = "The `--print-config=minimal` option doesn't work with standard input." ) ]
71
+ MinimalPathWithStdin ,
72
+ /// An io error during reading or writing.
73
+ #[ fail( display = "io error: {}" , _0) ]
74
+ IoError ( IoError ) ,
75
+ }
76
+
77
+ impl From < IoError > for OperationError {
78
+ fn from ( e : IoError ) -> OperationError {
79
+ OperationError :: IoError ( e)
80
+ }
66
81
}
67
82
68
83
/// Arguments to `--help`
@@ -152,11 +167,11 @@ fn make_opts() -> Options {
152
167
}
153
168
154
169
fn is_nightly ( ) -> bool {
155
- option_env ! ( "CFG_RELEASE_CHANNEL" ) . map_or ( false , |c| c == "nightly" || c == "dev" )
170
+ option_env ! ( "CFG_RELEASE_CHANNEL" ) . map_or ( true , |c| c == "nightly" || c == "dev" )
156
171
}
157
172
158
173
// Returned i32 is an exit code
159
- fn execute ( opts : & Options ) -> Result < i32 , failure :: Error > {
174
+ fn execute ( opts : & Options ) -> Result < i32 , FailureError > {
160
175
let matches = opts. parse ( env:: args ( ) . skip ( 1 ) ) ?;
161
176
let options = GetOptsOptions :: from_matches ( & matches) ?;
162
177
@@ -210,7 +225,7 @@ fn execute(opts: &Options) -> Result<i32, failure::Error> {
210
225
}
211
226
}
212
227
213
- fn format_string ( input : String , options : GetOptsOptions ) -> Result < i32 , failure :: Error > {
228
+ fn format_string ( input : String , options : GetOptsOptions ) -> Result < i32 , FailureError > {
214
229
// try to read config from local directory
215
230
let ( mut config, _) = load_config ( Some ( Path :: new ( "." ) ) , Some ( options. clone ( ) ) ) ?;
216
231
@@ -243,7 +258,7 @@ fn format(
243
258
files : Vec < PathBuf > ,
244
259
minimal_config_path : Option < String > ,
245
260
options : & GetOptsOptions ,
246
- ) -> Result < i32 , failure :: Error > {
261
+ ) -> Result < i32 , FailureError > {
247
262
options. verify_file_lines ( & files) ;
248
263
let ( config, config_path) = load_config ( None , Some ( options. clone ( ) ) ) ?;
249
264
@@ -385,7 +400,7 @@ fn print_version() {
385
400
println ! ( "rustfmt {}" , version_info) ;
386
401
}
387
402
388
- fn determine_operation ( matches : & Matches ) -> Result < Operation , ErrorKind > {
403
+ fn determine_operation ( matches : & Matches ) -> Result < Operation , OperationError > {
389
404
if matches. opt_present ( "h" ) {
390
405
let topic = matches. opt_str ( "h" ) ;
391
406
if topic == None {
@@ -395,22 +410,25 @@ fn determine_operation(matches: &Matches) -> Result<Operation, ErrorKind> {
395
410
} else if topic == Some ( "file-lines" . to_owned ( ) ) {
396
411
return Ok ( Operation :: Help ( HelpOp :: FileLines ) ) ;
397
412
} else {
398
- println ! ( "Unknown help topic: `{}`\n " , topic. unwrap( ) ) ;
399
- return Ok ( Operation :: Help ( HelpOp :: None ) ) ;
413
+ return Err ( OperationError :: UnknownHelpTopic ( topic. unwrap ( ) ) ) ;
400
414
}
401
415
}
416
+ let mut free_matches = matches. free . iter ( ) ;
402
417
403
418
let mut minimal_config_path = None ;
404
- if let Some ( ref kind) = matches. opt_str ( "print-config" ) {
405
- let path = matches. free . get ( 0 ) . cloned ( ) ;
406
- if kind == "default" {
407
- return Ok ( Operation :: ConfigOutputDefault { path } ) ;
408
- } else if kind == "current" {
409
- return Ok ( Operation :: ConfigOutputCurrent { path } ) ;
410
- } else if kind == "minimal" {
411
- minimal_config_path = path;
412
- if minimal_config_path. is_none ( ) {
413
- println ! ( "WARNING: PATH required for `--print-config minimal`" ) ;
419
+ if let Some ( kind) = matches. opt_str ( "print-config" ) {
420
+ let path = free_matches. next ( ) . cloned ( ) ;
421
+ match kind. as_str ( ) {
422
+ "default" => return Ok ( Operation :: ConfigOutputDefault { path } ) ,
423
+ "current" => return Ok ( Operation :: ConfigOutputCurrent { path } ) ,
424
+ "minimal" => {
425
+ minimal_config_path = path;
426
+ if minimal_config_path. is_none ( ) {
427
+ eprintln ! ( "WARNING: PATH required for `--print-config minimal`." ) ;
428
+ }
429
+ }
430
+ _ => {
431
+ return Err ( OperationError :: UnknownPrintConfigTopic ( kind) ) ;
414
432
}
415
433
}
416
434
}
@@ -419,17 +437,7 @@ fn determine_operation(matches: &Matches) -> Result<Operation, ErrorKind> {
419
437
return Ok ( Operation :: Version ) ;
420
438
}
421
439
422
- // if no file argument is supplied, read from stdin
423
- if matches. free . is_empty ( ) {
424
- let mut buffer = String :: new ( ) ;
425
- io:: stdin ( ) . read_to_string ( & mut buffer) ?;
426
-
427
- return Ok ( Operation :: Stdin { input : buffer } ) ;
428
- }
429
-
430
- let files: Vec < _ > = matches
431
- . free
432
- . iter ( )
440
+ let files: Vec < _ > = free_matches
433
441
. map ( |s| {
434
442
let p = PathBuf :: from ( s) ;
435
443
// we will do comparison later, so here tries to canonicalize first
@@ -438,6 +446,17 @@ fn determine_operation(matches: &Matches) -> Result<Operation, ErrorKind> {
438
446
} )
439
447
. collect ( ) ;
440
448
449
+ // if no file argument is supplied, read from stdin
450
+ if files. is_empty ( ) {
451
+ if minimal_config_path. is_some ( ) {
452
+ return Err ( OperationError :: MinimalPathWithStdin ) ;
453
+ }
454
+ let mut buffer = String :: new ( ) ;
455
+ io:: stdin ( ) . read_to_string ( & mut buffer) ?;
456
+
457
+ return Ok ( Operation :: Stdin { input : buffer } ) ;
458
+ }
459
+
441
460
Ok ( Operation :: Format {
442
461
files,
443
462
minimal_config_path,
@@ -464,7 +483,7 @@ struct GetOptsOptions {
464
483
}
465
484
466
485
impl GetOptsOptions {
467
- pub fn from_matches ( matches : & Matches ) -> Result < GetOptsOptions , failure :: Error > {
486
+ pub fn from_matches ( matches : & Matches ) -> Result < GetOptsOptions , FailureError > {
468
487
let mut options = GetOptsOptions :: default ( ) ;
469
488
options. verbose = matches. opt_present ( "verbose" ) ;
470
489
options. quiet = matches. opt_present ( "quiet" ) ;
@@ -598,15 +617,15 @@ impl CliOptions for GetOptsOptions {
598
617
}
599
618
}
600
619
601
- fn edition_from_edition_str ( edition_str : & str ) -> Result < Edition , failure :: Error > {
620
+ fn edition_from_edition_str ( edition_str : & str ) -> Result < Edition , FailureError > {
602
621
match edition_str {
603
622
"2015" => Ok ( Edition :: Edition2015 ) ,
604
623
"2018" => Ok ( Edition :: Edition2018 ) ,
605
624
_ => Err ( format_err ! ( "Invalid value for `--edition`" ) ) ,
606
625
}
607
626
}
608
627
609
- fn emit_mode_from_emit_str ( emit_str : & str ) -> Result < EmitMode , failure :: Error > {
628
+ fn emit_mode_from_emit_str ( emit_str : & str ) -> Result < EmitMode , FailureError > {
610
629
match emit_str {
611
630
"files" => Ok ( EmitMode :: Files ) ,
612
631
"stdout" => Ok ( EmitMode :: Stdout ) ,
0 commit comments