@@ -20,14 +20,16 @@ extern crate getopts;
20
20
use rustfmt:: { run, Input } ;
21
21
use rustfmt:: config:: { Config , WriteMode } ;
22
22
23
- use std:: env;
23
+ use std:: { env, error } ;
24
24
use std:: fs:: { self , File } ;
25
25
use std:: io:: { self , ErrorKind , Read , Write } ;
26
26
use std:: path:: { Path , PathBuf } ;
27
27
use std:: str:: FromStr ;
28
28
29
29
use getopts:: { Matches , Options } ;
30
30
31
+ type FmtError = Box < error:: Error + Send + Sync > ;
32
+ type FmtResult < T > = std:: result:: Result < T , FmtError > ;
31
33
32
34
/// Rustfmt operations.
33
35
enum Operation {
@@ -42,10 +44,6 @@ enum Operation {
42
44
Version ,
43
45
/// Print detailed configuration help.
44
46
ConfigHelp ,
45
- /// Invalid program input.
46
- InvalidInput {
47
- reason : String ,
48
- } ,
49
47
/// No file specified, read from stdin
50
48
Stdin {
51
49
input : String ,
@@ -55,7 +53,7 @@ enum Operation {
55
53
56
54
/// Try to find a project file in the given directory and its parents. Returns the path of a the
57
55
/// nearest project file if one exists, or `None` if no project file was found.
58
- fn lookup_project_file ( dir : & Path ) -> io :: Result < Option < PathBuf > > {
56
+ fn lookup_project_file ( dir : & Path ) -> FmtResult < Option < PathBuf > > {
59
57
let mut current = if dir. is_relative ( ) {
60
58
try!( env:: current_dir ( ) ) . join ( dir)
61
59
} else {
@@ -67,19 +65,17 @@ fn lookup_project_file(dir: &Path) -> io::Result<Option<PathBuf>> {
67
65
loop {
68
66
let config_file = current. join ( "rustfmt.toml" ) ;
69
67
match fs:: metadata ( & config_file) {
70
- Ok ( md) => {
71
- // Properly handle unlikely situation of a directory named `rustfmt.toml`.
72
- if md. is_file ( ) {
73
- return Ok ( Some ( config_file) ) ;
74
- }
75
- }
76
- // If it's not found, we continue searching; otherwise something went wrong and we
77
- // return the error.
68
+ // Only return if it's a file to handle the unlikely situation of a directory named
69
+ // `rustfmt.toml`.
70
+ Ok ( ref md) if md. is_file ( ) => return Ok ( Some ( config_file) ) ,
71
+ // Return the error if it's something other than `NotFound`; otherwise we didn't find
72
+ // the project file yet, and continue searching.
78
73
Err ( e) => {
79
74
if e. kind ( ) != ErrorKind :: NotFound {
80
- return Err ( e ) ;
75
+ return Err ( FmtError :: from ( e ) ) ;
81
76
}
82
77
}
78
+ _ => { }
83
79
}
84
80
85
81
// If the current directory has no parent, we're done searching.
@@ -93,7 +89,7 @@ fn lookup_project_file(dir: &Path) -> io::Result<Option<PathBuf>> {
93
89
///
94
90
/// Returns the `Config` to use, and the path of the project file if there was
95
91
/// one.
96
- fn resolve_config ( dir : & Path ) -> io :: Result < ( Config , Option < PathBuf > ) > {
92
+ fn resolve_config ( dir : & Path ) -> FmtResult < ( Config , Option < PathBuf > ) > {
97
93
let path = try!( lookup_project_file ( dir) ) ;
98
94
if path. is_none ( ) {
99
95
return Ok ( ( Config :: default ( ) , None ) ) ;
@@ -108,7 +104,7 @@ fn resolve_config(dir: &Path) -> io::Result<(Config, Option<PathBuf>)> {
108
104
/// read the given config file path recursively if present else read the project file path
109
105
fn match_cli_path_or_file ( config_path : Option < PathBuf > ,
110
106
input_file : & Path )
111
- -> io :: Result < ( Config , Option < PathBuf > ) > {
107
+ -> FmtResult < ( Config , Option < PathBuf > ) > {
112
108
113
109
if let Some ( config_file) = config_path {
114
110
let ( toml, path) = try!( resolve_config ( config_file. as_ref ( ) ) ) ;
@@ -119,7 +115,7 @@ fn match_cli_path_or_file(config_path: Option<PathBuf>,
119
115
resolve_config ( input_file)
120
116
}
121
117
122
- fn update_config ( config : & mut Config , matches : & Matches ) -> Result < ( ) , String > {
118
+ fn update_config ( config : & mut Config , matches : & Matches ) -> FmtResult < ( ) > {
123
119
config. verbose = matches. opt_present ( "verbose" ) ;
124
120
config. skip_children = matches. opt_present ( "skip-children" ) ;
125
121
@@ -130,11 +126,14 @@ fn update_config(config: &mut Config, matches: &Matches) -> Result<(), String> {
130
126
config. write_mode = write_mode;
131
127
Ok ( ( ) )
132
128
}
133
- Some ( Err ( _) ) => Err ( format ! ( "Invalid write-mode: {}" , write_mode. expect( "cannot happen" ) ) ) ,
129
+ Some ( Err ( _) ) => {
130
+ Err ( FmtError :: from ( format ! ( "Invalid write-mode: {}" ,
131
+ write_mode. expect( "cannot happen" ) ) ) )
132
+ }
134
133
}
135
134
}
136
135
137
- fn execute ( ) -> i32 {
136
+ fn make_opts ( ) -> Options {
138
137
let mut opts = Options :: new ( ) ;
139
138
opts. optflag ( "h" , "help" , "show this message" ) ;
140
139
opts. optflag ( "V" , "version" , "show version information" ) ;
@@ -154,32 +153,21 @@ fn execute() -> i32 {
154
153
found reverts to the input file path",
155
154
"[Path for the configuration file]" ) ;
156
155
157
- let matches = match opts. parse ( env:: args ( ) . skip ( 1 ) ) {
158
- Ok ( m) => m,
159
- Err ( e) => {
160
- print_usage ( & opts, & e. to_string ( ) ) ;
161
- return 1 ;
162
- }
163
- } ;
156
+ opts
157
+ }
164
158
165
- let operation = determine_operation ( & matches) ;
159
+ fn execute ( opts : & Options ) -> FmtResult < ( ) > {
160
+ let matches = try!( opts. parse ( env:: args ( ) . skip ( 1 ) ) ) ;
166
161
167
- match operation {
168
- Operation :: InvalidInput { reason } => {
169
- print_usage ( & opts, & reason) ;
170
- 1
171
- }
162
+ match try!( determine_operation ( & matches) ) {
172
163
Operation :: Help => {
173
164
print_usage ( & opts, "" ) ;
174
- 0
175
165
}
176
166
Operation :: Version => {
177
167
print_version ( ) ;
178
- 0
179
168
}
180
169
Operation :: ConfigHelp => {
181
170
Config :: print_docs ( ) ;
182
- 0
183
171
}
184
172
Operation :: Stdin { input, config_path } => {
185
173
// try to read config from local directory
@@ -190,7 +178,6 @@ fn execute() -> i32 {
190
178
config. write_mode = WriteMode :: Plain ;
191
179
192
180
run ( Input :: Text ( input) , & config) ;
193
- 0
194
181
}
195
182
Operation :: Format { files, config_path } => {
196
183
let mut config = Config :: default ( ) ;
@@ -221,21 +208,26 @@ fn execute() -> i32 {
221
208
config = config_tmp;
222
209
}
223
210
224
- if let Err ( e) = update_config ( & mut config, & matches) {
225
- print_usage ( & opts, & e) ;
226
- return 1 ;
227
- }
211
+ try!( update_config ( & mut config, & matches) ) ;
228
212
run ( Input :: File ( file) , & config) ;
229
213
}
230
- 0
231
214
}
232
215
}
216
+ Ok ( ( ) )
233
217
}
234
218
235
219
fn main ( ) {
236
220
let _ = env_logger:: init ( ) ;
237
- let exit_code = execute ( ) ;
238
221
222
+ let opts = make_opts ( ) ;
223
+
224
+ let exit_code = match execute ( & opts) {
225
+ Ok ( ..) => 0 ,
226
+ Err ( e) => {
227
+ print_usage ( & opts, & e. to_string ( ) ) ;
228
+ 1
229
+ }
230
+ } ;
239
231
// Make sure standard output is flushed before we exit.
240
232
std:: io:: stdout ( ) . flush ( ) . unwrap ( ) ;
241
233
@@ -261,17 +253,17 @@ fn print_version() {
261
253
option_env!( "CARGO_PKG_VERSION_PRE" ) . unwrap_or( "" ) ) ;
262
254
}
263
255
264
- fn determine_operation ( matches : & Matches ) -> Operation {
256
+ fn determine_operation ( matches : & Matches ) -> FmtResult < Operation > {
265
257
if matches. opt_present ( "h" ) {
266
- return Operation :: Help ;
258
+ return Ok ( Operation :: Help ) ;
267
259
}
268
260
269
261
if matches. opt_present ( "config-help" ) {
270
- return Operation :: ConfigHelp ;
262
+ return Ok ( Operation :: ConfigHelp ) ;
271
263
}
272
264
273
265
if matches. opt_present ( "version" ) {
274
- return Operation :: Version ;
266
+ return Ok ( Operation :: Version ) ;
275
267
}
276
268
277
269
// Read the config_path and convert to parent dir if a file is provided.
@@ -288,21 +280,18 @@ fn determine_operation(matches: &Matches) -> Operation {
288
280
if matches. free . is_empty ( ) {
289
281
290
282
let mut buffer = String :: new ( ) ;
291
- match io:: stdin ( ) . read_to_string ( & mut buffer) {
292
- Ok ( ..) => ( ) ,
293
- Err ( e) => return Operation :: InvalidInput { reason : e. to_string ( ) } ,
294
- }
283
+ try!( io:: stdin ( ) . read_to_string ( & mut buffer) ) ;
295
284
296
- return Operation :: Stdin {
285
+ return Ok ( Operation :: Stdin {
297
286
input : buffer,
298
287
config_path : config_path,
299
- } ;
288
+ } ) ;
300
289
}
301
290
302
291
let files: Vec < _ > = matches. free . iter ( ) . map ( PathBuf :: from) . collect ( ) ;
303
292
304
- Operation :: Format {
293
+ Ok ( Operation :: Format {
305
294
files : files,
306
295
config_path : config_path,
307
- }
296
+ } )
308
297
}
0 commit comments