@@ -174,10 +174,13 @@ impl Input {
174174 try_stream ! {
175175 let source = self . source. clone( ) ;
176176
177- let user_input_error = move |e: ErrorKind | RequestError :: UserInputContent ( source. clone( ) , Box :: new( e) ) ;
178- let discovered_input_error = |e: ErrorKind | RequestError :: GetInputContent ( self . source. clone( ) , Box :: new( e) ) ;
177+ let user_input_error =
178+ move |e: ErrorKind | RequestError :: UserInputContent ( source. clone( ) , Box :: new( e) ) ;
179+ let discovered_input_error =
180+ |e: ErrorKind | RequestError :: GetInputContent ( self . source. clone( ) , Box :: new( e) ) ;
179181
180- // Handle simple cases that don't need resolution
182+ // Handle simple cases that don't need resolution, and perform simple
183+ // checks for more complex cases.
181184 match self . source {
182185 InputSource :: RemoteUrl ( url) => {
183186 match resolver. url_contents( * url) . await {
@@ -187,8 +190,27 @@ impl Input {
187190 }
188191 return ;
189192 }
193+ InputSource :: FsPath ( ref path) => {
194+ let is_readable = std:: fs:: metadata( path) . and_then( |meta| {
195+ if meta. is_dir( ) {
196+ std:: fs:: read_dir( path) . map( |_| ( ) )
197+ } else {
198+ std:: fs:: File :: open( path) . map( |_| ( ) )
199+ }
200+ } ) ;
201+
202+ match is_readable {
203+ Ok ( _) => ( ) ,
204+ Err ( e) => Err ( user_input_error( ErrorKind :: ReadFileInput (
205+ e,
206+ path. to_path_buf( ) ,
207+ ) ) ) ?,
208+ }
209+ }
190210 InputSource :: Stdin => {
191- yield Self :: stdin_content( self . file_type_hint) . await . map_err( user_input_error) ?;
211+ yield Self :: stdin_content( self . file_type_hint)
212+ . await
213+ . map_err( user_input_error) ?;
192214 return ;
193215 }
194216 InputSource :: String ( ref s) => {
@@ -213,35 +235,37 @@ impl Input {
213235 match source_result {
214236 Ok ( source) => {
215237 let content_result = match source {
216- ResolvedInputSource :: FsPath ( path) => {
217- Self :: path_content( & path) . await
218- } ,
238+ ResolvedInputSource :: FsPath ( path) => Self :: path_content( & path) . await ,
219239 ResolvedInputSource :: RemoteUrl ( url) => {
220240 resolver. url_contents( * url) . await
221- } ,
241+ }
222242 ResolvedInputSource :: Stdin => {
223243 Self :: stdin_content( self . file_type_hint) . await
224- } ,
244+ }
225245 ResolvedInputSource :: String ( s) => {
226246 Ok ( Self :: string_content( & s, self . file_type_hint) )
227- } ,
247+ }
228248 } ;
229249
230250 match content_result {
231251 Err ( _) if skip_missing => ( ) ,
232- Err ( e) if matches!( & e, ErrorKind :: ReadFileInput ( io_err, _) if io_err. kind( ) == std:: io:: ErrorKind :: InvalidData ) => {
252+ Err ( e) if matches!( & e, ErrorKind :: ReadFileInput ( io_err, _) if io_err. kind( ) == std:: io:: ErrorKind :: InvalidData ) =>
253+ {
233254 // If the file contains invalid UTF-8 (e.g. binary), we skip it
234255 if let ErrorKind :: ReadFileInput ( _, path) = & e {
235- log:: warn!( "Skipping file with invalid UTF-8 content: {}" , path. display( ) ) ;
256+ log:: warn!(
257+ "Skipping file with invalid UTF-8 content: {}" ,
258+ path. display( )
259+ ) ;
236260 }
237- } ,
261+ }
238262 Err ( e) => Err ( discovered_input_error( e) ) ?,
239263 Ok ( content) => {
240264 sources_empty = false ;
241265 yield content
242266 }
243267 }
244- } ,
268+ }
245269 Err ( e) => Err ( discovered_input_error( e) ) ?,
246270 }
247271 }
0 commit comments