@@ -64,36 +64,36 @@ pub fn gt_int(value: f64, other_int: &BigInt) -> bool {
6464}
6565
6666pub fn parse_str ( literal : & str ) -> Option < f64 > {
67- if literal. starts_with ( '_' ) || literal. ends_with ( '_' ) {
68- return None ;
69- }
70-
71- let mut buf = String :: with_capacity ( literal. len ( ) ) ;
72- let mut last_tok: Option < char > = None ;
73- for c in literal. chars ( ) {
74- if !( c. is_ascii_alphanumeric ( ) || c == '_' || c == '+' || c == '-' || c == '.' ) {
75- return None ;
76- }
67+ parse_inner ( literal. trim ( ) . as_bytes ( ) )
68+ }
7769
78- if !c. is_ascii_alphanumeric ( ) {
79- if let Some ( l) = last_tok {
80- if !l. is_ascii_alphanumeric ( ) && !( c == '.' && ( l == '-' || l == '+' ) ) {
81- return None ;
82- }
83- }
84- }
70+ pub fn parse_bytes ( literal : & [ u8 ] ) -> Option < f64 > {
71+ parse_inner ( trim_slice ( literal, |b| b. is_ascii_whitespace ( ) ) )
72+ }
8573
86- if c != '_' {
87- buf. push ( c) ;
88- }
89- last_tok = Some ( c) ;
74+ fn trim_slice < T > ( v : & [ T ] , mut trim : impl FnMut ( & T ) -> bool ) -> & [ T ] {
75+ let mut it = v. iter ( ) ;
76+ // it.take_while_ref(&mut trim).for_each(drop);
77+ // hmm.. `&mut slice::Iter<_>` is not `Clone`
78+ // it.by_ref().rev().take_while_ref(&mut trim).for_each(drop);
79+ while it. clone ( ) . next ( ) . map_or ( false , & mut trim) {
80+ it. next ( ) ;
9081 }
91-
92- if let Ok ( f) = lexical_core:: parse ( buf. as_bytes ( ) ) {
93- Some ( f)
94- } else {
95- None
82+ while it. clone ( ) . next_back ( ) . map_or ( false , & mut trim) {
83+ it. next_back ( ) ;
9684 }
85+ it. as_slice ( )
86+ }
87+
88+ fn parse_inner ( literal : & [ u8 ] ) -> Option < f64 > {
89+ use lexical_parse_float:: {
90+ format:: PYTHON3_LITERAL , FromLexicalWithOptions , NumberFormatBuilder , Options ,
91+ } ;
92+ // lexical-core's format::PYTHON_STRING is inaccurate
93+ const PYTHON_STRING : u128 = NumberFormatBuilder :: rebuild ( PYTHON3_LITERAL )
94+ . no_special ( false )
95+ . build ( ) ;
96+ f64:: from_lexical_with_options :: < PYTHON_STRING > ( literal, & Options :: new ( ) ) . ok ( )
9797}
9898
9999pub fn is_integer ( v : f64 ) -> bool {
0 commit comments