@@ -292,30 +292,54 @@ impl FormatSpec {
292
292
}
293
293
294
294
fn add_magnitude_separators_for_char (
295
- magnitude_string : String ,
296
- interval : usize ,
297
- separator : char ,
295
+ magnitude_str : String ,
296
+ inter : i32 ,
297
+ sep : char ,
298
+ disp_digit_cnt : i32 ,
298
299
) -> String {
299
- let mut result = String :: new ( ) ;
300
-
301
300
// Don't add separators to the floating decimal point of numbers
302
- let mut parts = magnitude_string. splitn ( 2 , '.' ) ;
303
- let magnitude_integer_string = parts. next ( ) . unwrap ( ) ;
304
- let mut remaining: usize = magnitude_integer_string. len ( ) ;
305
- for c in magnitude_integer_string. chars ( ) {
306
- result. push ( c) ;
307
- remaining -= 1 ;
308
- if remaining % interval == 0 && remaining > 0 {
309
- result. push ( separator) ;
310
- }
311
- }
301
+ let mut parts = magnitude_str. splitn ( 2 , '.' ) ;
302
+ let magnitude_int_str = parts. next ( ) . unwrap ( ) . to_string ( ) ;
303
+ let dec_digit_cnt = magnitude_str. len ( ) as i32 - magnitude_int_str. len ( ) as i32 ;
304
+ let int_digit_cnt = disp_digit_cnt - dec_digit_cnt;
305
+ let mut result = FormatSpec :: separate_integer ( magnitude_int_str, inter, sep, int_digit_cnt) ;
312
306
if let Some ( part) = parts. next ( ) {
313
- result. push ( '.' ) ;
314
- result. push_str ( part) ;
307
+ result. push_str ( & format ! ( ".{}" , part) )
315
308
}
316
309
result
317
310
}
318
311
312
+ fn separate_integer (
313
+ magnitude_str : String ,
314
+ inter : i32 ,
315
+ sep : char ,
316
+ disp_digit_cnt : i32 ,
317
+ ) -> String {
318
+ let magnitude_len = magnitude_str. len ( ) as i32 ;
319
+ let offset = ( disp_digit_cnt % ( inter + 1 ) == 0 ) as i32 ;
320
+ let disp_digit_cnt = disp_digit_cnt + offset;
321
+ let pad_cnt = disp_digit_cnt - magnitude_len;
322
+ if pad_cnt > 0 {
323
+ // separate with 0 padding
324
+ let sep_cnt = disp_digit_cnt / ( inter + 1 ) ;
325
+ let padding = "0" . repeat ( ( pad_cnt - sep_cnt) as usize ) ;
326
+ let padded_num = format ! ( "{}{}" , padding, magnitude_str) ;
327
+ FormatSpec :: insert_separator ( padded_num, inter, sep, sep_cnt)
328
+ } else {
329
+ // separate without padding
330
+ let sep_cnt = ( magnitude_len - 1 ) / inter;
331
+ FormatSpec :: insert_separator ( magnitude_str, inter, sep, sep_cnt)
332
+ }
333
+ }
334
+
335
+ fn insert_separator ( mut magnitude_str : String , inter : i32 , sep : char , sep_cnt : i32 ) -> String {
336
+ let magnitude_len = magnitude_str. len ( ) as i32 ;
337
+ for i in 1 ..sep_cnt + 1 {
338
+ magnitude_str. insert ( ( magnitude_len - inter * i) as usize , sep) ;
339
+ }
340
+ magnitude_str
341
+ }
342
+
319
343
fn get_separator_interval ( & self ) -> usize {
320
344
match self . format_type {
321
345
Some ( FormatType :: Binary ) => 4 ,
@@ -330,26 +354,32 @@ impl FormatSpec {
330
354
}
331
355
}
332
356
333
- fn add_magnitude_separators ( & self , magnitude_string : String ) -> String {
334
- match self . grouping_option {
335
- Some ( FormatGrouping :: Comma ) => FormatSpec :: add_magnitude_separators_for_char (
336
- magnitude_string,
337
- self . get_separator_interval ( ) ,
338
- ',' ,
339
- ) ,
340
- Some ( FormatGrouping :: Underscore ) => FormatSpec :: add_magnitude_separators_for_char (
341
- magnitude_string,
342
- self . get_separator_interval ( ) ,
343
- '_' ,
344
- ) ,
345
- None => magnitude_string,
357
+ fn add_magnitude_separators ( & self , magnitude_str : String , prefix : & str ) -> String {
358
+ match & self . grouping_option {
359
+ Some ( fg) => {
360
+ let sep = match fg {
361
+ FormatGrouping :: Comma => ',' ,
362
+ FormatGrouping :: Underscore => '_' ,
363
+ } ;
364
+ let inter = self . get_separator_interval ( ) . try_into ( ) . unwrap ( ) ;
365
+ let magnitude_len = magnitude_str. len ( ) ;
366
+ let width = self . width . unwrap_or ( magnitude_len) as i32 - prefix. len ( ) as i32 ;
367
+ let disp_digit_cnt = cmp:: max ( width, magnitude_len as i32 ) ;
368
+ FormatSpec :: add_magnitude_separators_for_char (
369
+ magnitude_str,
370
+ inter,
371
+ sep,
372
+ disp_digit_cnt,
373
+ )
374
+ }
375
+ None => magnitude_str,
346
376
}
347
377
}
348
378
349
379
pub ( crate ) fn format_float ( & self , num : f64 ) -> Result < String , & ' static str > {
350
380
let precision = self . precision . unwrap_or ( 6 ) ;
351
381
let magnitude = num. abs ( ) ;
352
- let raw_magnitude_string_result : Result < String , & ' static str > = match self . format_type {
382
+ let raw_magnitude_str : Result < String , & ' static str > = match self . format_type {
353
383
Some ( FormatType :: FixedPointUpper ) => Ok ( float_ops:: format_fixed (
354
384
precision,
355
385
magnitude,
@@ -425,8 +455,6 @@ impl FormatSpec {
425
455
} ,
426
456
} ,
427
457
} ;
428
-
429
- let magnitude_string = self . add_magnitude_separators ( raw_magnitude_string_result?) ;
430
458
let format_sign = self . sign . unwrap_or ( FormatSign :: Minus ) ;
431
459
let sign_str = if num. is_sign_negative ( ) && !num. is_nan ( ) {
432
460
"-"
@@ -437,8 +465,8 @@ impl FormatSpec {
437
465
FormatSign :: MinusOrSpace => " " ,
438
466
}
439
467
} ;
440
-
441
- self . format_sign_and_align ( & magnitude_string , sign_str, FormatAlign :: Right )
468
+ let magnitude_str = self . add_magnitude_separators ( raw_magnitude_str? , sign_str ) ;
469
+ self . format_sign_and_align ( & magnitude_str , sign_str, FormatAlign :: Right )
442
470
}
443
471
444
472
#[ inline]
@@ -462,7 +490,7 @@ impl FormatSpec {
462
490
} else {
463
491
""
464
492
} ;
465
- let raw_magnitude_string_result : Result < String , & ' static str > = match self . format_type {
493
+ let raw_magnitude_str : Result < String , & ' static str > = match self . format_type {
466
494
Some ( FormatType :: Binary ) => self . format_int_radix ( magnitude, 2 ) ,
467
495
Some ( FormatType :: Decimal ) => self . format_int_radix ( magnitude, 10 ) ,
468
496
Some ( FormatType :: Octal ) => self . format_int_radix ( magnitude, 8 ) ,
@@ -504,7 +532,6 @@ impl FormatSpec {
504
532
} ,
505
533
None => self . format_int_radix ( magnitude, 10 ) ,
506
534
} ;
507
- let magnitude_string = self . add_magnitude_separators ( raw_magnitude_string_result?) ;
508
535
let format_sign = self . sign . unwrap_or ( FormatSign :: Minus ) ;
509
536
let sign_str = match num. sign ( ) {
510
537
Sign :: Minus => "-" ,
@@ -515,7 +542,8 @@ impl FormatSpec {
515
542
} ,
516
543
} ;
517
544
let sign_prefix = format ! ( "{}{}" , sign_str, prefix) ;
518
- self . format_sign_and_align ( & magnitude_string, & sign_prefix, FormatAlign :: Right )
545
+ let magnitude_str = self . add_magnitude_separators ( raw_magnitude_str?, & sign_prefix) ;
546
+ self . format_sign_and_align ( & magnitude_str, & sign_prefix, FormatAlign :: Right )
519
547
}
520
548
521
549
pub ( crate ) fn format_string ( & self , s : & str ) -> Result < String , & ' static str > {
0 commit comments