@@ -98,6 +98,7 @@ pub enum FormatType {
98
98
GeneralFormatUpper ,
99
99
FixedPointLower ,
100
100
FixedPointUpper ,
101
+ Percentage ,
101
102
}
102
103
103
104
#[ derive( Debug , PartialEq ) ]
@@ -232,11 +233,12 @@ fn parse_format_type(text: &str) -> (Option<FormatType>, &str) {
232
233
Some ( 'g' ) => ( Some ( FormatType :: GeneralFormatLower ) , chars. as_str ( ) ) ,
233
234
Some ( 'G' ) => ( Some ( FormatType :: GeneralFormatUpper ) , chars. as_str ( ) ) ,
234
235
Some ( 'n' ) => ( Some ( FormatType :: Number ) , chars. as_str ( ) ) ,
236
+ Some ( '%' ) => ( Some ( FormatType :: Percentage ) , chars. as_str ( ) ) ,
235
237
_ => ( None , text) ,
236
238
}
237
239
}
238
240
239
- fn parse_format_spec ( text : & str ) -> FormatSpec {
241
+ fn parse_format_spec ( text : & str ) -> Result < FormatSpec , & ' static str > {
240
242
let ( preconversor, after_preconversor) = parse_preconversor ( text) ;
241
243
let ( mut fill, mut align, after_align) = parse_fill_and_align ( after_preconversor) ;
242
244
let ( sign, after_sign) = parse_sign ( after_align) ;
@@ -245,14 +247,17 @@ fn parse_format_spec(text: &str) -> FormatSpec {
245
247
let ( width, after_width) = parse_number ( after_zero) ;
246
248
let ( grouping_option, after_grouping_option) = parse_grouping_option ( after_width) ;
247
249
let ( precision, after_precision) = parse_precision ( after_grouping_option) ;
248
- let ( format_type, _) = parse_format_type ( after_precision) ;
250
+ let ( format_type, after_format_type) = parse_format_type ( after_precision) ;
251
+ if !after_format_type. is_empty ( ) {
252
+ return Err ( "Invalid format spec" ) ;
253
+ }
249
254
250
255
if zero && fill. is_none ( ) {
251
256
fill. replace ( '0' ) ;
252
257
align = align. or ( Some ( FormatAlign :: AfterSign ) ) ;
253
258
}
254
259
255
- FormatSpec {
260
+ Ok ( FormatSpec {
256
261
preconversor,
257
262
fill,
258
263
align,
@@ -262,11 +267,11 @@ fn parse_format_spec(text: &str) -> FormatSpec {
262
267
grouping_option,
263
268
precision,
264
269
format_type,
265
- }
270
+ } )
266
271
}
267
272
268
273
impl FormatSpec {
269
- pub fn parse ( text : & str ) -> FormatSpec {
274
+ pub fn parse ( text : & str ) -> Result < FormatSpec , & ' static str > {
270
275
parse_format_spec ( text)
271
276
}
272
277
@@ -369,6 +374,11 @@ impl FormatSpec {
369
374
Some ( FormatType :: ExponentLower ) => {
370
375
Err ( "Format code 'e' for object of type 'float' not implemented yet" )
371
376
}
377
+ Some ( FormatType :: Percentage ) => match magnitude {
378
+ magnitude if magnitude. is_nan ( ) => Ok ( "nan%" . to_string ( ) ) ,
379
+ magnitude if magnitude. is_infinite ( ) => Ok ( "inf%" . to_string ( ) ) ,
380
+ _ => Ok ( format ! ( "{:.*}%" , precision, magnitude * 100.0 ) ) ,
381
+ } ,
372
382
None => {
373
383
match magnitude {
374
384
magnitude if magnitude. is_nan ( ) => Ok ( "nan" . to_string ( ) ) ,
@@ -443,6 +453,9 @@ impl FormatSpec {
443
453
_ => Err ( "Unable to convert int to float" ) ,
444
454
}
445
455
}
456
+ Some ( FormatType :: Percentage ) => {
457
+ Err ( "Format code '%' for object of type 'int' not implemented yet" )
458
+ }
446
459
None => Ok ( magnitude. to_str_radix ( 10 ) ) ,
447
460
} ;
448
461
if raw_magnitude_string_result. is_err ( ) {
@@ -525,7 +538,7 @@ pub enum FormatParseError {
525
538
impl FromStr for FormatSpec {
526
539
type Err = & ' static str ;
527
540
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
528
- Ok ( FormatSpec :: parse ( s) )
541
+ FormatSpec :: parse ( s)
529
542
}
530
543
}
531
544
0 commit comments