@@ -458,30 +458,31 @@ fn construct_committed_str(mem_info: &MemInfo, n2s: &dyn Fn(u64) -> String) -> S
458458
459459// Here's the `-h` `--human` flag processing logic
460460fn humanized ( kib : u64 , si : bool ) -> String {
461- let binding = {
462- let display = ByteSize :: kib ( kib) . display ( ) ;
463-
464- if si {
465- display. si ( )
466- } else {
467- display. iec ( )
468- }
461+ let b = ByteSize :: kib ( kib) . 0 ;
462+ let units = [ 'B' , 'K' , 'M' , 'G' , 'T' , 'P' ] ;
463+ let mut level = 0 ;
464+ let mut divisor = 1 ;
465+ while level < units. len ( ) - 1 && divisor * 100 <= b {
466+ divisor *= if si { 1000 } else { 1024 } ;
467+ level += 1 ;
468+ }
469+ if level == 0 {
470+ return format ! ( "{}{}" , b, units[ level] ) ;
469471 }
470- . to_string ( ) ;
471-
472- let split: Vec < & str > = binding. split ( ' ' ) . collect ( ) ;
473-
474- // TODO: finish the logic of automatic scale.
475- let num_string = String :: from ( split[ 0 ] ) ;
476472
477- let unit_string = {
478- let mut tmp = String :: from ( split[ 1 ] ) ;
479- if tmp != "B" {
480- tmp. pop ( ) ;
481- }
482- tmp
473+ let value = ( b as f64 ) / ( divisor as f64 ) ;
474+ let formatted_value = if ( value * 10.0 ) . round ( ) < 100.0 {
475+ format ! ( "{:.1}" , ( value * 10.0 ) . round( ) / 10.0 )
476+ } else {
477+ ( value as u64 ) . to_string ( )
483478 } ;
484- format ! ( "{}{}" , num_string, unit_string)
479+
480+ format ! (
481+ "{}{}{}" ,
482+ formatted_value,
483+ units[ level] . to_owned( ) ,
484+ if si { "" } else { "i" }
485+ )
485486}
486487
487488fn detect_unit ( arg : & ArgMatches ) -> fn ( u64 ) -> u64 {
@@ -541,8 +542,22 @@ mod test {
541542 }
542543
543544 #[ test]
544- fn test_humanized_unit_for_zero ( ) {
545- assert_eq ! ( "0B" , humanized( 0 , false ) ) ;
546- assert_eq ! ( "0B" , humanized( 0 , true ) ) ;
545+ fn test_humanized_unit ( ) {
546+ let test_cases = [
547+ ( 0 , false , "0B" ) ,
548+ ( 0 , true , "0B" ) ,
549+ ( 1023 , false , "1.0Mi" ) ,
550+ ( 1024 , true , "1.0M" ) ,
551+ ( 1024 , false , "1.0Mi" ) ,
552+ ( 1536 , true , "1.6M" ) ,
553+ ( 1536 , false , "1.5Mi" ) ,
554+ ( 8500 , true , "8.7M" ) ,
555+ ( 8500 , false , "8.3Mi" ) ,
556+ ( 10138 , false , "9.9Mi" ) ,
557+ ( 10230 , false , "9Mi" ) ,
558+ ] ;
559+ for & ( kib, si, expected) in & test_cases {
560+ assert_eq ! ( humanized( kib, si) , expected) ;
561+ }
547562 }
548563}
0 commit comments