Skip to content

Commit cfb9c93

Browse files
dannasmanyouknowone
authored andcommitted
add underline handling to float parsing
1 parent 36f34ce commit cfb9c93

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

literal/src/float.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ pub fn parse_str(literal: &str) -> Option<f64> {
66
parse_inner(literal.trim().as_bytes())
77
}
88

9+
fn strip_separators(literal: &[u8]) -> Option<Vec<u8>>{
10+
let mut prev = b'\0';
11+
let mut dup = Vec::<u8>::new();
12+
for p in literal {
13+
if *p == b'_' {
14+
// Underscores are only allowed after digits.
15+
if !prev.is_ascii_digit() {
16+
return None;
17+
}
18+
} else {
19+
dup.push(*p);
20+
// Underscores are only allowed before digits.
21+
if prev == b'_' && !p.is_ascii_digit() {
22+
return None;
23+
}
24+
}
25+
prev = *p;
26+
}
27+
28+
// Underscores are not allowed at the end.
29+
if prev == b'_' {
30+
return None;
31+
}
32+
33+
Some(dup)
34+
}
35+
936
pub fn parse_bytes(literal: &[u8]) -> Option<f64> {
1037
parse_inner(trim_slice(literal, |b| b.is_ascii_whitespace()))
1138
}
@@ -28,12 +55,16 @@ fn parse_inner(literal: &[u8]) -> Option<f64> {
2855
use lexical_parse_float::{
2956
format::PYTHON3_LITERAL, FromLexicalWithOptions, NumberFormatBuilder, Options,
3057
};
58+
59+
// Use custom function for underline handling for now.
60+
// For further information see https://github.com/Alexhuszagh/rust-lexical/issues/96.
61+
let stripped = strip_separators(literal)?;
62+
3163
// lexical-core's format::PYTHON_STRING is inaccurate
3264
const PYTHON_STRING: u128 = NumberFormatBuilder::rebuild(PYTHON3_LITERAL)
3365
.no_special(false)
34-
.consecutive_digit_separator(false)
3566
.build();
36-
f64::from_lexical_with_options::<PYTHON_STRING>(literal, &Options::new()).ok()
67+
f64::from_lexical_with_options::<PYTHON_STRING>(&stripped, &Options::new()).ok()
3768
}
3869

3970
pub fn is_integer(v: f64) -> bool {

0 commit comments

Comments
 (0)