@@ -21,6 +21,7 @@ use crate::error::print_error;
2121use crate :: exec;
2222use crate :: exit_codes:: { ExitCode , merge_exitcodes} ;
2323use crate :: filesystem;
24+ use crate :: filter:: SortKey ;
2425use crate :: output;
2526
2627/// The receiver thread can either be buffering results or directly streaming to the console.
@@ -411,7 +412,18 @@ impl WorkerState {
411412 // This will be set to `Some` if the `--exec` argument was supplied.
412413 if let Some ( ref cmd) = config. command {
413414 if cmd. in_batch_mode ( ) {
414- exec:: batch ( rx. into_iter ( ) . flatten ( ) , cmd, config)
415+ let mut results: Vec < WorkerResult > = rx. into_iter ( ) . flatten ( ) . collect ( ) ;
416+ if let Some ( sort_key) = config. sort_key {
417+ sort_worker_results ( & mut results, sort_key) ;
418+ }
419+ exec:: batch ( results. into_iter ( ) , cmd, config)
420+ } else if let Some ( sort_key) = config. sort_key {
421+ // With --sort, we must collect all results before dispatching,
422+ // and run sequentially so the order is preserved.
423+
424+ let mut results: Vec < WorkerResult > = rx. into_iter ( ) . flatten ( ) . collect ( ) ;
425+ sort_worker_results ( & mut results, sort_key) ;
426+ return exec:: job ( results. into_iter ( ) , cmd, config) ;
415427 } else {
416428 thread:: scope ( |scope| {
417429 // Each spawned job will store its thread handle in here.
@@ -663,6 +675,35 @@ impl WorkerState {
663675 }
664676}
665677
678+ fn sort_worker_results ( results : & mut Vec < WorkerResult > , sort_key : SortKey ) {
679+ results. sort_by ( |a, b| {
680+ // Errors sort to the end; two errors are considered equal
681+ let ( WorkerResult :: Entry ( a) , WorkerResult :: Entry ( b) ) = ( a, b) else {
682+ return match ( a, b) {
683+ ( WorkerResult :: Error ( _) , WorkerResult :: Entry ( _) ) => std:: cmp:: Ordering :: Greater ,
684+ ( WorkerResult :: Entry ( _) , WorkerResult :: Error ( _) ) => std:: cmp:: Ordering :: Less ,
685+ _ => std:: cmp:: Ordering :: Equal ,
686+ } ;
687+ } ;
688+
689+ match sort_key {
690+ SortKey :: Path => a. path ( ) . cmp ( b. path ( ) ) ,
691+ SortKey :: Size => {
692+ let size = |e : & DirEntry | e. metadata ( ) . map ( |m| m. len ( ) ) . unwrap_or ( 0 ) ;
693+ size ( a) . cmp ( & size ( b) )
694+ }
695+ SortKey :: Created => {
696+ let time = |e : & DirEntry | e. metadata ( ) . and_then ( |m| m. created ( ) . ok ( ) ) ;
697+ time ( a) . cmp ( & time ( b) )
698+ }
699+ SortKey :: Modified => {
700+ let time = |e : & DirEntry | e. metadata ( ) . and_then ( |m| m. modified ( ) . ok ( ) ) ;
701+ time ( a) . cmp ( & time ( b) )
702+ }
703+ }
704+ } ) ;
705+ }
706+
666707fn search_str_for_entry < ' a > (
667708 entry_path : & ' a std:: path:: Path ,
668709 full_path_base : Option < & std:: path:: Path > ,
0 commit comments