@@ -22,7 +22,7 @@ use rustfmt::config::{Config, WriteMode};
22
22
23
23
use std:: env;
24
24
use std:: fs:: { self , File } ;
25
- use std:: io:: { self , Read , Write } ;
25
+ use std:: io:: { self , ErrorKind , Read , Write } ;
26
26
use std:: path:: { Path , PathBuf } ;
27
27
28
28
use getopts:: { Matches , Options } ;
@@ -43,39 +43,55 @@ enum Operation {
43
43
Stdin ( String , WriteMode ) ,
44
44
}
45
45
46
- /// Try to find a project file in the input file directory and its parents.
47
- fn lookup_project_file ( input_file : & Path ) -> io:: Result < PathBuf > {
48
- let mut current = if input_file . is_relative ( ) {
49
- try!( env:: current_dir ( ) ) . join ( input_file )
46
+ /// Try to find a project file in the given directory and its parents.
47
+ fn lookup_project_file ( dir : & Path ) -> io:: Result < Option < PathBuf > > {
48
+ let mut current = if dir . is_relative ( ) {
49
+ try!( env:: current_dir ( ) ) . join ( dir )
50
50
} else {
51
- input_file . to_path_buf ( )
51
+ dir . to_path_buf ( )
52
52
} ;
53
53
54
54
current = try!( fs:: canonicalize ( current) ) ;
55
55
56
56
loop {
57
57
let config_file = current. join ( "rustfmt.toml" ) ;
58
- if let Ok ( md) = fs:: metadata ( & config_file) {
59
- // Properly handle unlikely situation of a directory named `rustfmt.toml`.
60
- if md. is_file ( ) {
61
- return Ok ( config_file) ;
58
+ match fs:: metadata ( & config_file) {
59
+ Ok ( md) => {
60
+ // Properly handle unlikely situation of a directory named `rustfmt.toml`.
61
+ if md. is_file ( ) {
62
+ return Ok ( Some ( config_file) ) ;
63
+ }
64
+ }
65
+ // If it's not found, we continue searching; otherwise something went wrong and we
66
+ // return the error.
67
+ Err ( e) => {
68
+ if e. kind ( ) != ErrorKind :: NotFound {
69
+ return Err ( e) ;
70
+ }
62
71
}
63
72
}
64
73
65
74
// If the current directory has no parent, we're done searching.
66
75
if !current. pop ( ) {
67
- return Err ( io :: Error :: new ( io :: ErrorKind :: NotFound , "Config not found" ) ) ;
76
+ return Ok ( None ) ;
68
77
}
69
78
}
70
79
}
71
80
72
- /// Try to find a project file. If it's found, read it.
73
- fn lookup_and_read_project_file ( input_file : & Path ) -> io:: Result < ( PathBuf , String ) > {
74
- let path = try!( lookup_project_file ( input_file) ) ;
81
+ /// Resolve the config for input in `dir`.
82
+ ///
83
+ /// Returns the `Config` to use, and the path of the project file if there was
84
+ /// one.
85
+ fn resolve_config ( dir : & Path ) -> io:: Result < ( Config , Option < PathBuf > ) > {
86
+ let path = try!( lookup_project_file ( dir) ) ;
87
+ if path. is_none ( ) {
88
+ return Ok ( ( Config :: default ( ) , None ) ) ;
89
+ }
90
+ let path = path. unwrap ( ) ;
75
91
let mut file = try!( File :: open ( & path) ) ;
76
92
let mut toml = String :: new ( ) ;
77
93
try!( file. read_to_string ( & mut toml) ) ;
78
- Ok ( ( path , toml ) )
94
+ Ok ( ( Config :: from_toml ( & toml ) , Some ( path ) ) )
79
95
}
80
96
81
97
fn update_config ( config : & mut Config , matches : & Matches ) {
@@ -127,25 +143,22 @@ fn execute() -> i32 {
127
143
}
128
144
Operation :: Stdin ( input, write_mode) => {
129
145
// try to read config from local directory
130
- let config = match lookup_and_read_project_file ( & Path :: new ( "." ) ) {
131
- Ok ( ( _, toml) ) => Config :: from_toml ( & toml) ,
132
- Err ( _) => Default :: default ( ) ,
133
- } ;
146
+ let ( config, _) = resolve_config ( & env:: current_dir ( ) . unwrap ( ) )
147
+ . expect ( "Error resolving config" ) ;
134
148
135
149
run_from_stdin ( input, write_mode, & config) ;
136
150
0
137
151
}
138
152
Operation :: Format ( files, write_mode) => {
139
153
for file in files {
140
- let mut config = match lookup_and_read_project_file ( & file) {
141
- Ok ( ( path, toml) ) => {
142
- println ! ( "Using rustfmt config file {} for {}" ,
143
- path. display( ) ,
144
- file. display( ) ) ;
145
- Config :: from_toml ( & toml)
146
- }
147
- Err ( _) => Default :: default ( ) ,
148
- } ;
154
+ let ( mut config, path) = resolve_config ( file. parent ( ) . unwrap ( ) )
155
+ . expect ( & format ! ( "Error resolving config for {}" ,
156
+ file. display( ) ) ) ;
157
+ if let Some ( path) = path {
158
+ println ! ( "Using rustfmt config file {} for {}" ,
159
+ path. display( ) ,
160
+ file. display( ) ) ;
161
+ }
149
162
150
163
update_config ( & mut config, & matches) ;
151
164
run ( & file, write_mode, & config) ;
0 commit comments