@@ -404,16 +404,70 @@ impl<'gctx> Source for RecursivePathSource<'gctx> {
404
404
}
405
405
}
406
406
407
+ /// Type that abstracts over [`gix::dir::entry::Kind`] and [`fs::FileType`].
408
+ #[ derive( Debug , Clone , Copy ) ]
409
+ enum FileType {
410
+ File ,
411
+ Dir ,
412
+ Symlink ,
413
+ Other ,
414
+ }
415
+
416
+ impl From < fs:: FileType > for FileType {
417
+ fn from ( value : fs:: FileType ) -> Self {
418
+ if value. is_file ( ) {
419
+ FileType :: File
420
+ } else if value. is_dir ( ) {
421
+ FileType :: Dir
422
+ } else if value. is_symlink ( ) {
423
+ FileType :: Symlink
424
+ } else {
425
+ FileType :: Other
426
+ }
427
+ }
428
+ }
429
+
430
+ impl From < gix:: dir:: entry:: Kind > for FileType {
431
+ fn from ( value : gix:: dir:: entry:: Kind ) -> Self {
432
+ use gix:: dir:: entry:: Kind ;
433
+ match value {
434
+ Kind :: Untrackable => FileType :: Other ,
435
+ Kind :: File => FileType :: File ,
436
+ Kind :: Symlink => FileType :: Symlink ,
437
+ Kind :: Directory | Kind :: Repository => FileType :: Dir ,
438
+ }
439
+ }
440
+ }
441
+
407
442
/// [`PathBuf`] with extra metadata.
408
443
#[ derive( Clone , Debug ) ]
409
444
pub struct PathEntry {
410
445
path : PathBuf ,
446
+ ty : FileType ,
411
447
}
412
448
413
449
impl PathEntry {
414
450
pub fn into_path_buf ( self ) -> PathBuf {
415
451
self . path
416
452
}
453
+
454
+ /// Similar to [`std::path::Path::is_file`]
455
+ /// but doesn't follow the symbolic link nor make any system call
456
+ pub fn is_file ( & self ) -> bool {
457
+ matches ! ( self . ty, FileType :: File )
458
+ }
459
+
460
+ /// Similar to [`std::path::Path::is_dir`]
461
+ /// but doesn't follow the symbolic link nor make any system call
462
+ pub fn is_dir ( & self ) -> bool {
463
+ matches ! ( self . ty, FileType :: Dir )
464
+ }
465
+
466
+ /// Similar to [`std::path::Path::is_symlink`]
467
+ /// but doesn't follow the symbolic link nor make any system call
468
+ pub fn is_symlink ( & self ) -> bool {
469
+ matches ! ( self . ty, FileType :: Symlink )
470
+ }
417
471
}
418
472
419
473
impl std:: ops:: Deref for PathEntry {
@@ -727,7 +781,10 @@ fn list_files_gix(
727
781
} else if ( filter) ( & file_path, is_dir) {
728
782
assert ! ( !is_dir) ;
729
783
trace ! ( " found {}" , file_path. display( ) ) ;
730
- files. push ( PathEntry { path : file_path } ) ;
784
+ files. push ( PathEntry {
785
+ path : file_path,
786
+ ty : kind. map ( Into :: into) . unwrap_or ( FileType :: Other ) ,
787
+ } ) ;
731
788
}
732
789
}
733
790
@@ -782,8 +839,15 @@ fn list_files_walk(
782
839
Ok ( entry) => {
783
840
let file_type = entry. file_type ( ) ;
784
841
if file_type. is_file ( ) || file_type. is_symlink ( ) {
842
+ // We follow_links(true) here so check if entry was created from a symlink
843
+ let ty = if entry. path_is_symlink ( ) {
844
+ FileType :: Symlink
845
+ } else {
846
+ file_type. into ( )
847
+ } ;
785
848
ret. push ( PathEntry {
786
849
path : entry. into_path ( ) ,
850
+ ty,
787
851
} ) ;
788
852
}
789
853
}
@@ -800,6 +864,7 @@ fn list_files_walk(
800
864
// still hit the IO error if they do access it thereafter.
801
865
Some ( path) => ret. push ( PathEntry {
802
866
path : path. to_path_buf ( ) ,
867
+ ty : FileType :: Other ,
803
868
} ) ,
804
869
None => return Err ( err. into ( ) ) ,
805
870
} ,
0 commit comments