@@ -247,7 +247,18 @@ impl FromStr for Numeric {
247247 fn from_str ( value : & str ) -> Result < Self , Self :: Err > {
248248 let mut s = Scanner :: new ( value) ;
249249 s. eat_whitespace ( ) ;
250- let prefix = s. eat_while ( |c : char | !c. is_numeric ( ) && c != '-' ) ;
250+
251+ let prefix = {
252+ // Eat non-numeric characters and leading zeros.
253+ let start = s. cursor ( ) ;
254+ s. eat_while ( |c : char | !c. is_numeric ( ) && c != '-' ) ;
255+ let zeros = s. eat_while ( '0' ) ;
256+ if !zeros. is_empty ( ) && s. peek ( ) . is_none_or ( |c| !c. is_numeric ( ) ) {
257+ // Uneat the last zero if the value is just zero.
258+ s. uneat ( ) ;
259+ }
260+ s. from ( start)
261+ } ;
251262
252263 let value = number ( & mut s) . ok_or ( NumericError :: NoNumber ) ?;
253264 let space_after_value = s. eat_whitespace ( ) ;
@@ -329,23 +340,18 @@ pub enum NumericError {
329340 MissingDelimiter ,
330341}
331342
332- /// Eat a number from the scanner.
333- /// The number can be positive, negative, or zero, but can't have leading zeros.
343+ /// Eat a number from the scanner, assuming leading whitespaces and zeros have
344+ /// already been eaten.
345+ ///
346+ /// The number can be positive, negative, or zero.
334347fn number ( s : & mut Scanner ) -> Option < i32 > {
335- let start = s. cursor ( ) ;
336-
337348 let negative = s. eat_if ( '-' ) ;
338- let leading_zero = s. eat_if ( '0' ) ;
339349 let num = s. eat_while ( |c : char | c. is_numeric ( ) ) ;
340-
341- match ( leading_zero, num. is_empty ( ) ) {
342- ( true , true ) => Some ( 0 ) ,
343- ( false , false ) => num. parse :: < i32 > ( ) . ok ( ) . map ( |n| if negative { -n } else { n } ) ,
344- _ => {
345- s. jump ( start) ;
346- None
347- }
350+ if num. is_empty ( ) {
351+ return None ;
348352 }
353+
354+ num. parse :: < i32 > ( ) . ok ( ) . map ( |n| if negative { -n } else { n } )
349355}
350356
351357impl Display for Numeric {
0 commit comments