@@ -77,7 +77,13 @@ impl SuffixType {
77
77
/// Convert a number into a magnitude and a multi-byte unit suffix.
78
78
///
79
79
/// The returned string has a maximum length of 5 chars, for example: "1.1kB", "999kB", "1MB".
80
- pub ( crate ) fn to_magnitude_and_suffix ( n : u128 , suffix_type : SuffixType ) -> String {
80
+ /// `add_tracing_zero` allows to add tracing zero for values in 0 < x <= 9
81
+ ///
82
+ pub ( crate ) fn to_magnitude_and_suffix (
83
+ n : u128 ,
84
+ suffix_type : SuffixType ,
85
+ add_tracing_zero : bool ,
86
+ ) -> String {
81
87
let bases = suffix_type. bases ( ) ;
82
88
let suffixes = suffix_type. suffixes ( ) ;
83
89
let mut i = 0 ;
@@ -91,14 +97,22 @@ pub(crate) fn to_magnitude_and_suffix(n: u128, suffix_type: SuffixType) -> Strin
91
97
let suffix = suffixes[ i] ;
92
98
93
99
if rem == 0 {
94
- format ! ( "{quot}{suffix}" )
100
+ if add_tracing_zero && !suffix. is_empty ( ) && quot != 0 && quot <= 9 {
101
+ format ! ( "{quot}.0{suffix}" )
102
+ } else {
103
+ format ! ( "{quot}{suffix}" )
104
+ }
95
105
} else {
96
106
let tenths_place = rem / ( bases[ i] / 10 ) ;
97
107
98
108
if rem % ( bases[ i] / 10 ) == 0 {
99
109
format ! ( "{quot}.{tenths_place}{suffix}" )
100
110
} else if tenths_place + 1 == 10 || quot >= 10 {
101
- format ! ( "{}{suffix}" , quot + 1 )
111
+ if add_tracing_zero && !suffix. is_empty ( ) && quot != 0 && quot < 9 {
112
+ format ! ( "{}.0{suffix}" , quot + 1 )
113
+ } else {
114
+ format ! ( "{}{suffix}" , quot + 1 )
115
+ }
102
116
} else {
103
117
format ! ( "{quot}.{}{suffix}" , tenths_place + 1 )
104
118
}
@@ -150,6 +164,18 @@ impl BlockSize {
150
164
Self :: Bytes ( n) => n,
151
165
}
152
166
}
167
+
168
+ pub ( crate ) fn to_header ( & self ) -> String {
169
+ match self {
170
+ Self :: Bytes ( n) => {
171
+ if n % 1024 == 0 && n % 1000 != 0 {
172
+ to_magnitude_and_suffix ( * n as u128 , SuffixType :: Iec , false )
173
+ } else {
174
+ to_magnitude_and_suffix ( * n as u128 , SuffixType :: Si , false )
175
+ }
176
+ }
177
+ }
178
+ }
153
179
}
154
180
155
181
impl Default for BlockSize {
@@ -196,9 +222,9 @@ impl fmt::Display for BlockSize {
196
222
match self {
197
223
Self :: Bytes ( n) => {
198
224
let s = if n % 1024 == 0 && n % 1000 != 0 {
199
- to_magnitude_and_suffix ( * n as u128 , SuffixType :: Iec )
225
+ to_magnitude_and_suffix ( * n as u128 , SuffixType :: Iec , true )
200
226
} else {
201
- to_magnitude_and_suffix ( * n as u128 , SuffixType :: Si )
227
+ to_magnitude_and_suffix ( * n as u128 , SuffixType :: Si , true )
202
228
} ;
203
229
204
230
write ! ( f, "{s}" )
@@ -216,75 +242,121 @@ mod tests {
216
242
217
243
#[ test]
218
244
fn test_to_magnitude_and_suffix_powers_of_1024 ( ) {
219
- assert_eq ! ( to_magnitude_and_suffix( 1024 , SuffixType :: Iec ) , "1K" ) ;
220
- assert_eq ! ( to_magnitude_and_suffix( 2048 , SuffixType :: Iec ) , "2K" ) ;
221
- assert_eq ! ( to_magnitude_and_suffix( 4096 , SuffixType :: Iec ) , "4K" ) ;
222
- assert_eq ! ( to_magnitude_and_suffix( 1024 * 1024 , SuffixType :: Iec ) , "1M" ) ;
245
+ assert_eq ! ( to_magnitude_and_suffix( 1024 , SuffixType :: Iec , true ) , "1.0K" ) ;
246
+ assert_eq ! ( to_magnitude_and_suffix( 10240 , SuffixType :: Iec , true ) , "10K" ) ;
247
+ assert_eq ! ( to_magnitude_and_suffix( 2048 , SuffixType :: Iec , false ) , "2K" ) ;
223
248
assert_eq ! (
224
- to_magnitude_and_suffix( 2 * 1024 * 1024 , SuffixType :: Iec ) ,
225
- "2M "
249
+ to_magnitude_and_suffix( 1024 * 40 , SuffixType :: Iec , false ) ,
250
+ "40K "
226
251
) ;
227
252
assert_eq ! (
228
- to_magnitude_and_suffix( 1024 * 1024 * 1024 , SuffixType :: Iec ) ,
229
- "1G "
253
+ to_magnitude_and_suffix( 1024 * 1024 , SuffixType :: Iec , true ) ,
254
+ "1.0M "
230
255
) ;
231
256
assert_eq ! (
232
- to_magnitude_and_suffix( 34 * 1024 * 1024 * 1024 , SuffixType :: Iec ) ,
257
+ to_magnitude_and_suffix( 2 * 1024 * 1024 , SuffixType :: Iec , true ) ,
258
+ "2.0M"
259
+ ) ;
260
+ assert_eq ! (
261
+ to_magnitude_and_suffix( 1024 * 1024 * 1024 , SuffixType :: Iec , true ) ,
262
+ "1.0G"
263
+ ) ;
264
+ assert_eq ! (
265
+ to_magnitude_and_suffix( 34 * 1024 * 1024 * 1024 , SuffixType :: Iec , true ) ,
233
266
"34G"
234
267
) ;
235
268
}
236
269
237
270
#[ test]
238
271
#[ allow( clippy:: cognitive_complexity) ]
239
272
fn test_to_magnitude_and_suffix_not_powers_of_1024 ( ) {
240
- assert_eq ! ( to_magnitude_and_suffix( 1 , SuffixType :: Si ) , "1B" ) ;
241
- assert_eq ! ( to_magnitude_and_suffix( 999 , SuffixType :: Si ) , "999B" ) ;
242
-
243
- assert_eq ! ( to_magnitude_and_suffix( 1000 , SuffixType :: Si ) , "1kB" ) ;
244
- assert_eq ! ( to_magnitude_and_suffix( 1001 , SuffixType :: Si ) , "1.1kB" ) ;
245
- assert_eq ! ( to_magnitude_and_suffix( 1023 , SuffixType :: Si ) , "1.1kB" ) ;
246
- assert_eq ! ( to_magnitude_and_suffix( 1025 , SuffixType :: Si ) , "1.1kB" ) ;
247
- assert_eq ! ( to_magnitude_and_suffix( 10_001 , SuffixType :: Si ) , "11kB" ) ;
248
- assert_eq ! ( to_magnitude_and_suffix( 999_000 , SuffixType :: Si ) , "999kB" ) ;
249
-
250
- assert_eq ! ( to_magnitude_and_suffix( 999_001 , SuffixType :: Si ) , "1MB" ) ;
251
- assert_eq ! ( to_magnitude_and_suffix( 999_999 , SuffixType :: Si ) , "1MB" ) ;
252
- assert_eq ! ( to_magnitude_and_suffix( 1_000_000 , SuffixType :: Si ) , "1MB" ) ;
253
- assert_eq ! ( to_magnitude_and_suffix( 1_000_001 , SuffixType :: Si ) , "1.1MB" ) ;
254
- assert_eq ! ( to_magnitude_and_suffix( 1_100_000 , SuffixType :: Si ) , "1.1MB" ) ;
255
- assert_eq ! ( to_magnitude_and_suffix( 1_100_001 , SuffixType :: Si ) , "1.2MB" ) ;
256
- assert_eq ! ( to_magnitude_and_suffix( 1_900_000 , SuffixType :: Si ) , "1.9MB" ) ;
257
- assert_eq ! ( to_magnitude_and_suffix( 1_900_001 , SuffixType :: Si ) , "2MB" ) ;
258
- assert_eq ! ( to_magnitude_and_suffix( 9_900_000 , SuffixType :: Si ) , "9.9MB" ) ;
259
- assert_eq ! ( to_magnitude_and_suffix( 9_900_001 , SuffixType :: Si ) , "10MB" ) ;
273
+ assert_eq ! ( to_magnitude_and_suffix( 1 , SuffixType :: Si , true ) , "1.0B" ) ;
274
+ assert_eq ! ( to_magnitude_and_suffix( 999 , SuffixType :: Si , true ) , "999B" ) ;
275
+
276
+ assert_eq ! ( to_magnitude_and_suffix( 1000 , SuffixType :: Si , true ) , "1.0kB" ) ;
277
+ assert_eq ! ( to_magnitude_and_suffix( 1001 , SuffixType :: Si , true ) , "1.1kB" ) ;
278
+ assert_eq ! ( to_magnitude_and_suffix( 1023 , SuffixType :: Si , true ) , "1.1kB" ) ;
279
+ assert_eq ! ( to_magnitude_and_suffix( 1025 , SuffixType :: Si , true ) , "1.1kB" ) ;
260
280
assert_eq ! (
261
- to_magnitude_and_suffix( 999_000_000 , SuffixType :: Si ) ,
281
+ to_magnitude_and_suffix( 10_001 , SuffixType :: Si , true ) ,
282
+ "11kB"
283
+ ) ;
284
+ assert_eq ! (
285
+ to_magnitude_and_suffix( 999_000 , SuffixType :: Si , true ) ,
286
+ "999kB"
287
+ ) ;
288
+
289
+ assert_eq ! (
290
+ to_magnitude_and_suffix( 999_001 , SuffixType :: Si , true ) ,
291
+ "1.0MB"
292
+ ) ;
293
+ assert_eq ! (
294
+ to_magnitude_and_suffix( 999_999 , SuffixType :: Si , true ) ,
295
+ "1.0MB"
296
+ ) ;
297
+ assert_eq ! (
298
+ to_magnitude_and_suffix( 1_000_000 , SuffixType :: Si , true ) ,
299
+ "1.0MB"
300
+ ) ;
301
+ assert_eq ! (
302
+ to_magnitude_and_suffix( 1_000_001 , SuffixType :: Si , true ) ,
303
+ "1.1MB"
304
+ ) ;
305
+ assert_eq ! (
306
+ to_magnitude_and_suffix( 1_100_000 , SuffixType :: Si , true ) ,
307
+ "1.1MB"
308
+ ) ;
309
+ assert_eq ! (
310
+ to_magnitude_and_suffix( 1_100_001 , SuffixType :: Si , true ) ,
311
+ "1.2MB"
312
+ ) ;
313
+ assert_eq ! (
314
+ to_magnitude_and_suffix( 1_900_000 , SuffixType :: Si , true ) ,
315
+ "1.9MB"
316
+ ) ;
317
+ assert_eq ! (
318
+ to_magnitude_and_suffix( 1_900_001 , SuffixType :: Si , true ) ,
319
+ "2.0MB"
320
+ ) ;
321
+ assert_eq ! (
322
+ to_magnitude_and_suffix( 9_900_000 , SuffixType :: Si , true ) ,
323
+ "9.9MB"
324
+ ) ;
325
+ assert_eq ! (
326
+ to_magnitude_and_suffix( 9_900_001 , SuffixType :: Si , true ) ,
327
+ "10MB"
328
+ ) ;
329
+ assert_eq ! (
330
+ to_magnitude_and_suffix( 999_000_000 , SuffixType :: Si , true ) ,
262
331
"999MB"
263
332
) ;
264
333
265
- assert_eq ! ( to_magnitude_and_suffix( 999_000_001 , SuffixType :: Si ) , "1GB" ) ;
266
334
assert_eq ! (
267
- to_magnitude_and_suffix( 1_000_000_000 , SuffixType :: Si ) ,
268
- "1GB"
335
+ to_magnitude_and_suffix( 999_000_001 , SuffixType :: Si , true ) ,
336
+ "1.0GB"
337
+ ) ;
338
+ assert_eq ! (
339
+ to_magnitude_and_suffix( 1_000_000_000 , SuffixType :: Si , true ) ,
340
+ "1.0GB"
269
341
) ;
270
342
assert_eq ! (
271
- to_magnitude_and_suffix( 1_000_000_001 , SuffixType :: Si ) ,
343
+ to_magnitude_and_suffix( 1_000_000_001 , SuffixType :: Si , true ) ,
272
344
"1.1GB"
273
345
) ;
274
346
}
275
347
276
348
#[ test]
277
349
fn test_block_size_display ( ) {
278
- assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 1024 ) ) , "1K " ) ;
279
- assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 2 * 1024 ) ) , "2K " ) ;
280
- assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 3 * 1024 * 1024 ) ) , "3M " ) ;
350
+ assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 1024 ) ) , "1.0K " ) ;
351
+ assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 2 * 1024 ) ) , "2.0K " ) ;
352
+ assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 3 * 1024 * 1024 ) ) , "3.0M " ) ;
281
353
}
282
354
283
355
#[ test]
284
356
fn test_block_size_display_multiples_of_1000_and_1024 ( ) {
285
357
assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 128_000 ) ) , "128kB" ) ;
286
358
assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 1000 * 1024 ) ) , "1.1MB" ) ;
287
- assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 1_000_000_000_000 ) ) , "1TB " ) ;
359
+ assert_eq ! ( format!( "{}" , BlockSize :: Bytes ( 1_000_000_000_000 ) ) , "1.0TB " ) ;
288
360
}
289
361
290
362
#[ test]
0 commit comments