@@ -155,16 +155,17 @@ fn parse_fill_and_align(text: &str) -> (Option<char>, Option<FormatAlign>, &str)
155155 }
156156}
157157
158- fn parse_number ( text : & str ) -> ( Option < usize > , & str ) {
158+ fn parse_number ( text : & str ) -> Result < ( Option < usize > , & str ) , & ' static str > {
159159 let num_digits: usize = get_num_digits ( text) ;
160160 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" )
162168 }
163- // This should never fail
164- (
165- Some ( text[ ..num_digits] . parse :: < usize > ( ) . unwrap ( ) ) ,
166- & text[ num_digits..] ,
167- )
168169}
169170
170171fn parse_sign ( text : & str ) -> ( Option < FormatSign > , & str ) {
@@ -193,19 +194,19 @@ fn parse_zero(text: &str) -> (bool, &str) {
193194 }
194195}
195196
196- fn parse_precision ( text : & str ) -> ( Option < usize > , & str ) {
197+ fn parse_precision ( text : & str ) -> Result < ( Option < usize > , & str ) , & ' static str > {
197198 let mut chars = text. chars ( ) ;
198- match chars. next ( ) {
199+ Ok ( match chars. next ( ) {
199200 Some ( '.' ) => {
200- let ( size, remaining) = parse_number ( & chars. as_str ( ) ) ;
201+ let ( size, remaining) = parse_number ( & chars. as_str ( ) ) ? ;
201202 if size. is_some ( ) {
202203 ( size, remaining)
203204 } else {
204205 ( None , text)
205206 }
206207 }
207208 _ => ( None , text) ,
208- }
209+ } )
209210}
210211
211212fn parse_grouping_option ( text : & str ) -> ( Option < FormatGrouping > , & str ) {
@@ -239,14 +240,15 @@ fn parse_format_type(text: &str) -> (Option<FormatType>, &str) {
239240}
240241
241242fn parse_format_spec ( text : & str ) -> Result < FormatSpec , & ' static str > {
243+ // get_integer in CPython
242244 let ( preconversor, after_preconversor) = parse_preconversor ( text) ;
243245 let ( mut fill, mut align, after_align) = parse_fill_and_align ( after_preconversor) ;
244246 let ( sign, after_sign) = parse_sign ( after_align) ;
245247 let ( alternate_form, after_alternate_form) = parse_alternate_form ( after_sign) ;
246248 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) ? ;
248250 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) ? ;
250252 let ( format_type, after_format_type) = parse_format_type ( after_precision) ;
251253 if !after_format_type. is_empty ( ) {
252254 return Err ( "Invalid format specifier" ) ;
0 commit comments