@@ -155,16 +155,17 @@ fn parse_fill_and_align(text: &str) -> (Option<char>, Option<FormatAlign>, &str)
155
155
}
156
156
}
157
157
158
- fn parse_number ( text : & str ) -> ( Option < usize > , & str ) {
158
+ fn parse_number ( text : & str ) -> Result < ( Option < usize > , & str ) , & ' static str > {
159
159
let num_digits: usize = get_num_digits ( text) ;
160
160
if num_digits == 0 {
161
- return ( None , text) ;
161
+ return Ok ( ( None , text) ) ;
162
+ }
163
+ if let Ok ( num) = text[ ..num_digits] . parse :: < usize > ( ) {
164
+ Ok ( ( Some ( num) , & text[ num_digits..] ) )
165
+ } else {
166
+ // NOTE: this condition is different from CPython
167
+ Err ( "Too many decimal digits in format string" )
162
168
}
163
- // This should never fail
164
- (
165
- Some ( text[ ..num_digits] . parse :: < usize > ( ) . unwrap ( ) ) ,
166
- & text[ num_digits..] ,
167
- )
168
169
}
169
170
170
171
fn parse_sign ( text : & str ) -> ( Option < FormatSign > , & str ) {
@@ -193,19 +194,19 @@ fn parse_zero(text: &str) -> (bool, &str) {
193
194
}
194
195
}
195
196
196
- fn parse_precision ( text : & str ) -> ( Option < usize > , & str ) {
197
+ fn parse_precision ( text : & str ) -> Result < ( Option < usize > , & str ) , & ' static str > {
197
198
let mut chars = text. chars ( ) ;
198
- match chars. next ( ) {
199
+ Ok ( match chars. next ( ) {
199
200
Some ( '.' ) => {
200
- let ( size, remaining) = parse_number ( & chars. as_str ( ) ) ;
201
+ let ( size, remaining) = parse_number ( & chars. as_str ( ) ) ? ;
201
202
if size. is_some ( ) {
202
203
( size, remaining)
203
204
} else {
204
205
( None , text)
205
206
}
206
207
}
207
208
_ => ( None , text) ,
208
- }
209
+ } )
209
210
}
210
211
211
212
fn parse_grouping_option ( text : & str ) -> ( Option < FormatGrouping > , & str ) {
@@ -239,14 +240,15 @@ fn parse_format_type(text: &str) -> (Option<FormatType>, &str) {
239
240
}
240
241
241
242
fn parse_format_spec ( text : & str ) -> Result < FormatSpec , & ' static str > {
243
+ // get_integer in CPython
242
244
let ( preconversor, after_preconversor) = parse_preconversor ( text) ;
243
245
let ( mut fill, mut align, after_align) = parse_fill_and_align ( after_preconversor) ;
244
246
let ( sign, after_sign) = parse_sign ( after_align) ;
245
247
let ( alternate_form, after_alternate_form) = parse_alternate_form ( after_sign) ;
246
248
let ( zero, after_zero) = parse_zero ( after_alternate_form) ;
247
- let ( width, after_width) = parse_number ( after_zero) ;
249
+ let ( width, after_width) = parse_number ( after_zero) ? ;
248
250
let ( grouping_option, after_grouping_option) = parse_grouping_option ( after_width) ;
249
- let ( precision, after_precision) = parse_precision ( after_grouping_option) ;
251
+ let ( precision, after_precision) = parse_precision ( after_grouping_option) ? ;
250
252
let ( format_type, after_format_type) = parse_format_type ( after_precision) ;
251
253
if !after_format_type. is_empty ( ) {
252
254
return Err ( "Invalid format specifier" ) ;
0 commit comments