4747//! case_sensitive: false,
4848//! require_literal_separator: false,
4949//! require_literal_leading_dot: false,
50+ //! follows_link: false,
5051//! };
5152//! for entry in glob_with("local/*a*", &options).unwrap() {
5253//! if let Ok(path) = entry {
@@ -299,8 +300,13 @@ impl fmt::Display for GlobError {
299300 }
300301}
301302
302- fn is_dir ( p : & Path ) -> bool {
303- fs:: metadata ( p) . map ( |m| m. is_dir ( ) ) . unwrap_or ( false )
303+ fn is_dir ( p : & Path , follows_link : bool ) -> bool {
304+ let metadata = if follows_link {
305+ fs:: metadata ( p)
306+ } else {
307+ fs:: symlink_metadata ( p)
308+ } ;
309+ metadata. map ( |m| m. is_dir ( ) ) . unwrap_or ( false )
304310}
305311
306312/// An alias for a glob iteration result.
@@ -343,7 +349,8 @@ impl Iterator for Paths {
343349 // idx -1: was already checked by fill_todo, maybe path was '.' or
344350 // '..' that we can't match here because of normalization.
345351 if idx == !0 as usize {
346- if self . require_dir && !is_dir ( & path) {
352+ if self . require_dir && !is_dir ( & path,
353+ self . options . follows_link ) {
347354 continue ;
348355 }
349356 return Some ( Ok ( path) ) ;
@@ -358,7 +365,7 @@ impl Iterator for Paths {
358365 next += 1 ;
359366 }
360367
361- if is_dir ( & path) {
368+ if is_dir ( & path, self . options . follows_link ) {
362369 // the path is a directory, so it's a match
363370
364371 // push this directory's contents
@@ -401,7 +408,8 @@ impl Iterator for Paths {
401408 // *AND* its children so we don't need to check the
402409 // children
403410
404- if !self . require_dir || is_dir ( & path) {
411+ if !self . require_dir || is_dir ( & path,
412+ self . options . follows_link ) {
405413 return Some ( Ok ( path) ) ;
406414 }
407415 } else {
@@ -804,7 +812,7 @@ fn fill_todo(todo: &mut Vec<Result<(PathBuf, usize), GlobError>>,
804812 } ;
805813
806814 let pattern = & patterns[ idx] ;
807- let is_dir = is_dir ( path) ;
815+ let is_dir = is_dir ( path, options . follows_link ) ;
808816 let curdir = path == Path :: new ( "." ) ;
809817 match pattern_as_str ( pattern) {
810818 Some ( s) => {
@@ -957,6 +965,10 @@ pub struct MatchOptions {
957965 /// conventionally considered hidden on Unix systems and it might be
958966 /// desirable to skip them when listing files.
959967 pub require_literal_leading_dot : bool ,
968+
969+ /// Whether ot not paths that are symbolic links are followed
970+ /// during the walk.
971+ pub follows_link : bool ,
960972}
961973
962974impl MatchOptions {
@@ -970,14 +982,16 @@ impl MatchOptions {
970982 /// MatchOptions {
971983 /// case_sensitive: true,
972984 /// require_literal_separator: false,
973- /// require_literal_leading_dot: false
985+ /// require_literal_leading_dot: false,
986+ /// follows_link: false,
974987 /// }
975988 /// ```
976989 pub fn new ( ) -> MatchOptions {
977990 MatchOptions {
978991 case_sensitive : true ,
979992 require_literal_separator : false ,
980993 require_literal_leading_dot : false ,
994+ follows_link : false ,
981995 }
982996 }
983997}
@@ -1219,6 +1233,7 @@ mod test {
12191233 case_sensitive : false ,
12201234 require_literal_separator : false ,
12211235 require_literal_leading_dot : false ,
1236+ follows_link : false ,
12221237 } ;
12231238
12241239 assert ! ( pat. matches_with( "aBcDeFg" , & options) ) ;
@@ -1237,11 +1252,13 @@ mod test {
12371252 case_sensitive : false ,
12381253 require_literal_separator : false ,
12391254 require_literal_leading_dot : false ,
1255+ follows_link : false ,
12401256 } ;
12411257 let options_case_sensitive = MatchOptions {
12421258 case_sensitive : true ,
12431259 require_literal_separator : false ,
12441260 require_literal_leading_dot : false ,
1261+ follows_link : false ,
12451262 } ;
12461263
12471264 assert ! ( pat_within. matches_with( "a" , & options_case_insensitive) ) ;
@@ -1260,11 +1277,13 @@ mod test {
12601277 case_sensitive : true ,
12611278 require_literal_separator : true ,
12621279 require_literal_leading_dot : false ,
1280+ follows_link : false ,
12631281 } ;
12641282 let options_not_require_literal = MatchOptions {
12651283 case_sensitive : true ,
12661284 require_literal_separator : false ,
12671285 require_literal_leading_dot : false ,
1286+ follows_link : false ,
12681287 } ;
12691288
12701289 assert ! ( Pattern :: new( "abc/def" ) . unwrap( ) . matches_with( "abc/def" , & options_require_literal) ) ;
@@ -1299,11 +1318,13 @@ mod test {
12991318 case_sensitive : true ,
13001319 require_literal_separator : false ,
13011320 require_literal_leading_dot : true ,
1321+ follows_link : false ,
13021322 } ;
13031323 let options_not_require_literal_leading_dot = MatchOptions {
13041324 case_sensitive : true ,
13051325 require_literal_separator : false ,
13061326 require_literal_leading_dot : false ,
1327+ follows_link : false ,
13071328 } ;
13081329
13091330 let f = |options| Pattern :: new ( "*.txt" ) . unwrap ( ) . matches_with ( ".hello.txt" , options) ;
0 commit comments