@@ -190,89 +190,111 @@ impl<'a> DigitInfo<'a> {
190
190
}
191
191
}
192
192
193
+ fn split_digit_parts ( & self ) -> ( & str , Option < & str > , Option < ( char , & str ) > ) {
194
+ let digits = self . digits ;
195
+
196
+ let mut integer = digits;
197
+ let mut fraction = None ;
198
+ let mut exponent = None ;
199
+
200
+ if self . float {
201
+ for ( i, c) in digits. char_indices ( ) {
202
+ match c {
203
+ '.' => {
204
+ integer = & digits[ ..i] ;
205
+ fraction = Some ( & digits[ i + 1 ..] ) ;
206
+ } ,
207
+ 'e' | 'E' => {
208
+ if integer. len ( ) > i {
209
+ integer = & digits[ ..i] ;
210
+ } else {
211
+ fraction = Some ( & digits[ integer. len ( ) + 1 ..i] ) ;
212
+ } ;
213
+ exponent = Some ( ( c, & digits[ i + 1 ..] ) ) ;
214
+ break ;
215
+ } ,
216
+ _ => { } ,
217
+ }
218
+ }
219
+ }
220
+
221
+ ( integer, fraction, exponent)
222
+ }
223
+
193
224
/// Returns literal formatted in a sensible way.
194
225
crate fn grouping_hint ( & self ) -> String {
226
+ let mut output = String :: new ( ) ;
227
+
228
+ if let Some ( prefix) = self . prefix {
229
+ output. push_str ( prefix) ;
230
+ }
231
+
195
232
let group_size = self . radix . suggest_grouping ( ) ;
196
- if self . digits . contains ( '.' ) {
197
- let mut parts = self . digits . split ( '.' ) ;
198
- let int_part_hint = parts
199
- . next ( )
200
- . expect ( "split always returns at least one element" )
233
+
234
+ let ( integer, fraction, exponent) = & self . split_digit_parts ( ) ;
235
+
236
+ let int_digits: Vec < _ > = integer. chars ( ) . rev ( ) . filter ( |& c| c != '_' ) . collect ( ) ;
237
+ let int_part_hint = int_digits
238
+ . chunks ( group_size)
239
+ . map ( |chunk| chunk. iter ( ) . rev ( ) . collect ( ) )
240
+ . rev ( )
241
+ . collect :: < Vec < String > > ( )
242
+ . join ( "_" ) ;
243
+
244
+ // Pad leading hexidecimal group with zeros
245
+ if self . radix == Radix :: Hexadecimal {
246
+ debug_assert ! ( group_size > 0 ) ;
247
+ let first_group_size = ( int_digits. len ( ) + group_size - 1 ) % group_size + 1 ;
248
+ for _ in 0 ..group_size - first_group_size {
249
+ output. push ( '0' ) ;
250
+ }
251
+ }
252
+
253
+ output. push_str ( & int_part_hint) ;
254
+
255
+ if let Some ( fraction) = fraction {
256
+ let frac_part_hint = fraction
201
257
. chars ( )
202
- . rev ( )
203
258
. filter ( |& c| c != '_' )
204
259
. collect :: < Vec < _ > > ( )
205
260
. chunks ( group_size)
206
- . map ( |chunk| chunk. iter ( ) . rev ( ) . collect ( ) )
207
- . rev ( )
261
+ . map ( |chunk| chunk. iter ( ) . collect ( ) )
208
262
. collect :: < Vec < String > > ( )
209
263
. join ( "_" ) ;
210
- let frac_part_hint = parts
211
- . next ( )
212
- . expect ( "already checked that there is a `.`" )
264
+
265
+ output. push ( '.' ) ;
266
+ output. push_str ( & frac_part_hint) ;
267
+ }
268
+
269
+ if let Some ( ( separator, exponent) ) = exponent {
270
+ let after_e_hint = exponent
213
271
. chars ( )
272
+ . rev ( )
214
273
. filter ( |& c| c != '_' )
215
274
. collect :: < Vec < _ > > ( )
216
- . chunks ( group_size)
217
- . map ( |chunk| chunk. iter ( ) . collect ( ) )
218
- . collect :: < Vec < String > > ( )
219
- . join ( "_" ) ;
220
- let suffix_hint = match self . suffix {
221
- Some ( suffix) if is_mistyped_float_suffix ( suffix) => format ! ( "_f{}" , & suffix[ 1 ..] ) ,
222
- Some ( suffix) => suffix. to_string ( ) ,
223
- None => String :: new ( ) ,
224
- } ;
225
- format ! ( "{}.{}{}" , int_part_hint, frac_part_hint, suffix_hint)
226
- } else if self . float && ( self . digits . contains ( 'E' ) || self . digits . contains ( 'e' ) ) {
227
- let which_e = if self . digits . contains ( 'E' ) { 'E' } else { 'e' } ;
228
- let parts: Vec < & str > = self . digits . split ( which_e) . collect ( ) ;
229
- let filtered_digits_vec_0 = parts[ 0 ] . chars ( ) . filter ( |& c| c != '_' ) . rev ( ) . collect :: < Vec < _ > > ( ) ;
230
- let filtered_digits_vec_1 = parts[ 1 ] . chars ( ) . filter ( |& c| c != '_' ) . rev ( ) . collect :: < Vec < _ > > ( ) ;
231
- let before_e_hint = filtered_digits_vec_0
232
- . chunks ( group_size)
233
- . map ( |chunk| chunk. iter ( ) . rev ( ) . collect ( ) )
234
- . rev ( )
235
- . collect :: < Vec < String > > ( )
236
- . join ( "_" ) ;
237
- let after_e_hint = filtered_digits_vec_1
238
275
. chunks ( group_size)
239
276
. map ( |chunk| chunk. iter ( ) . rev ( ) . collect ( ) )
240
277
. rev ( )
241
278
. collect :: < Vec < String > > ( )
242
279
. join ( "_" ) ;
243
- let suffix_hint = match self . suffix {
244
- Some ( suffix) if is_mistyped_float_suffix ( suffix) => format ! ( "_f{}" , & suffix[ 1 ..] ) ,
245
- Some ( suffix) => suffix. to_string ( ) ,
246
- None => String :: new ( ) ,
247
- } ;
248
- format ! (
249
- "{}{}{}{}{}" ,
250
- self . prefix. unwrap_or( "" ) ,
251
- before_e_hint,
252
- which_e,
253
- after_e_hint,
254
- suffix_hint
255
- )
256
- } else {
257
- let filtered_digits_vec = self . digits . chars ( ) . filter ( |& c| c != '_' ) . rev ( ) . collect :: < Vec < _ > > ( ) ;
258
- let mut hint = filtered_digits_vec
259
- . chunks ( group_size)
260
- . map ( |chunk| chunk. iter ( ) . rev ( ) . collect ( ) )
261
- . rev ( )
262
- . collect :: < Vec < String > > ( )
263
- . join ( "_" ) ;
264
- // Forces hexadecimal values to be grouped by 4 being filled with zeroes (e.g 0x00ab_cdef)
265
- let nb_digits_to_fill = filtered_digits_vec. len ( ) % 4 ;
266
- if self . radix == Radix :: Hexadecimal && nb_digits_to_fill != 0 {
267
- hint = format ! ( "{:0>4}{}" , & hint[ ..nb_digits_to_fill] , & hint[ nb_digits_to_fill..] ) ;
280
+
281
+ output. push ( * separator) ;
282
+ output. push_str ( & after_e_hint) ;
283
+ }
284
+
285
+ if let Some ( suffix) = self . suffix {
286
+ if self . float && is_mistyped_float_suffix ( suffix) {
287
+ output. push_str ( "_f" ) ;
288
+ output. push_str ( & suffix[ 1 ..] ) ;
289
+ } else if is_mistyped_suffix ( suffix) {
290
+ output. push_str ( "_i" ) ;
291
+ output. push_str ( & suffix[ 1 ..] ) ;
292
+ } else {
293
+ output. push_str ( suffix) ;
268
294
}
269
- let suffix_hint = match self . suffix {
270
- Some ( suffix) if is_mistyped_suffix ( suffix) => format ! ( "_i{}" , & suffix[ 1 ..] ) ,
271
- Some ( suffix) => suffix. to_string ( ) ,
272
- None => String :: new ( ) ,
273
- } ;
274
- format ! ( "{}{}{}" , self . prefix. unwrap_or( "" ) , hint, suffix_hint)
275
295
}
296
+
297
+ output
276
298
}
277
299
}
278
300
0 commit comments