@@ -24,7 +24,7 @@ use crate::filesystem;
2424use crate :: output;
2525
2626/// The receiver thread can either be buffering results or directly streaming to the console.
27- #[ derive( PartialEq ) ]
27+ #[ derive( Copy , Clone , PartialEq ) ]
2828enum ReceiverMode {
2929 /// Receiver is still buffering in order to sort the results, if the search finishes fast
3030 /// enough.
@@ -241,6 +241,7 @@ impl<'a, W: Write> ReceiverBuffer<'a, W> {
241241 self . stream ( ) ?;
242242 }
243243 Err ( RecvTimeoutError :: Disconnected ) => {
244+ // Note: This branch is called when all the results are walked/exhausted.
244245 return self . stop ( ) ;
245246 }
246247 }
@@ -280,9 +281,22 @@ impl<'a, W: Write> ReceiverBuffer<'a, W> {
280281
281282 /// Stop looping.
282283 fn stop ( & mut self ) -> Result < ( ) , ExitCode > {
283- if self . mode == ReceiverMode :: Buffering {
284- self . buffer . sort ( ) ;
285- self . stream ( ) ?;
284+ match ( self . mode , self . config . sort_key ) {
285+ ( ReceiverMode :: Buffering , None ) => {
286+ self . buffer . sort ( ) ;
287+ self . stream ( ) ?;
288+ }
289+ ( ReceiverMode :: Buffering , Some ( sort_key) ) => {
290+ sort_dir_entry_results ( & mut self . buffer , sort_key) ;
291+ self . stream ( ) ?;
292+ }
293+ ( ReceiverMode :: Streaming , None ) => { }
294+ ( ReceiverMode :: Streaming , Some ( _) ) => {
295+ // We force Buffering mode in Config construction if --sort is set by setting the timeout to almost infinity.
296+ unreachable ! (
297+ "--sort cannot work in Streaming mode. Buffering mode is forced in Config construction."
298+ ) ;
299+ }
286300 }
287301
288302 if self . config . quiet {
@@ -674,36 +688,30 @@ impl WorkerState {
674688 }
675689}
676690
691+ fn dir_entry_key_fn ( sort_key : SortKey ) -> Box < dyn Fn ( & DirEntry ) -> Option < SortKeyValue > > {
692+ match sort_key {
693+ SortKey :: Path => Box :: new ( |e| Some ( SortKeyValue :: Path ( e. path ( ) . to_path_buf ( ) ) ) ) ,
694+ SortKey :: Size => Box :: new ( |e| e. metadata ( ) . map ( |m| SortKeyValue :: Size ( m. len ( ) ) ) ) ,
695+ SortKey :: Created => {
696+ Box :: new ( |e| e. metadata ( ) . map ( |m| SortKeyValue :: Time ( m. created ( ) . ok ( ) ) ) )
697+ }
698+ SortKey :: Modified => {
699+ Box :: new ( |e| e. metadata ( ) . map ( |m| SortKeyValue :: Time ( m. modified ( ) . ok ( ) ) ) )
700+ }
701+ }
702+ }
703+
704+ fn sort_dir_entry_results ( results : & mut [ DirEntry ] , sort_key : SortKey ) {
705+ let key_fn = dir_entry_key_fn ( sort_key) ;
706+ results. sort_by_cached_key ( |e| key_fn ( e) ) ;
707+ }
708+
677709fn sort_worker_results ( results : & mut [ WorkerResult ] , sort_key : SortKey ) {
678- // Build the key extractor once, based on sort_key.
679- // Returns None for errors, pushing them to the end naturally via Ord on Option.
680- let key_fn: Box < dyn Fn ( & WorkerResult ) -> Option < SortKeyValue > > = match sort_key {
681- SortKey :: Path => Box :: new ( |r| match r {
682- WorkerResult :: Entry ( e) => Some ( SortKeyValue :: Path ( e. path ( ) . to_path_buf ( ) ) ) ,
683- WorkerResult :: Error ( _) => None ,
684- } ) ,
685- SortKey :: Size => Box :: new ( |r| match r {
686- WorkerResult :: Entry ( e) => Some ( SortKeyValue :: Size (
687- e. metadata ( ) . map ( |m| m. len ( ) ) . unwrap_or ( 0 ) ,
688- ) ) ,
689- WorkerResult :: Error ( _) => None ,
690- } ) ,
691- SortKey :: Created => Box :: new ( |r| match r {
692- WorkerResult :: Entry ( e) => Some ( SortKeyValue :: Time (
693- e. metadata ( ) . and_then ( |m| m. created ( ) . ok ( ) ) ,
694- ) ) ,
695- WorkerResult :: Error ( _) => None ,
696- } ) ,
697- SortKey :: Modified => Box :: new ( |r| match r {
698- WorkerResult :: Entry ( e) => Some ( SortKeyValue :: Time (
699- e. metadata ( ) . and_then ( |m| m. modified ( ) . ok ( ) ) ,
700- ) ) ,
701- WorkerResult :: Error ( _) => None ,
702- } ) ,
703- } ;
704-
705- // Use sort_by_cached_key to avoid recomputing the key for each comparison.
706- results. sort_by_cached_key ( |r| key_fn ( r) ) ;
710+ let key_fn = dir_entry_key_fn ( sort_key) ;
711+ results. sort_by_cached_key ( |r| match r {
712+ WorkerResult :: Entry ( e) => key_fn ( e) ,
713+ WorkerResult :: Error ( _) => None ,
714+ } ) ;
707715}
708716
709717/// Comparable key values, one variant per SortKey.
0 commit comments