Fix number parser grabbing comma
This commit is contained in:
parent
a480e5a096
commit
d87c2cf165
60
src/lib.rs
60
src/lib.rs
@ -262,15 +262,31 @@ impl JSON {
|
|||||||
n += 1;
|
n += 1;
|
||||||
} else if self.chars[n] >= '1' && self.chars[n] <= '9' && n < max {
|
} else if self.chars[n] >= '1' && self.chars[n] <= '9' && n < max {
|
||||||
n += 1;
|
n += 1;
|
||||||
while self.chars[n].is_ascii_digit() && n < max {
|
loop {
|
||||||
n += 1;
|
if n + 1 > max {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.chars[n + 1].is_ascii_digit() {
|
||||||
|
n += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.chars[n] == '.' && n < max {
|
if self.chars[n] == '.' && n < max {
|
||||||
n += 1;
|
n += 1;
|
||||||
while self.chars[n].is_ascii_digit() && n < max {
|
loop {
|
||||||
n += 1;
|
if n + 1 > max {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.chars[n + 1].is_ascii_digit() {
|
||||||
|
n += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,25 +296,36 @@ impl JSON {
|
|||||||
if self.chars[n] == '-' || self.chars[n] == '+' && n < max {
|
if self.chars[n] == '-' || self.chars[n] == '+' && n < max {
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
|
// expect digit
|
||||||
|
loop {
|
||||||
|
if n + 1 > max {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
while self.chars[n].is_ascii_digit() && n < max {
|
if self.chars[n + 1].is_ascii_digit() {
|
||||||
n += 1;
|
n += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are numeric digits attempt to parse the digits as a number
|
||||||
if n > start {
|
if n > start {
|
||||||
let end = if n < self.chars.len() {
|
let end = if n < self.chars.len() {
|
||||||
n
|
n
|
||||||
} else {
|
} else {
|
||||||
self.chars.len()
|
max
|
||||||
};
|
};
|
||||||
|
|
||||||
let str = String::from_iter(&self.chars[start..=end]);
|
let str = String::from_iter(&self.chars[start..=end]);
|
||||||
self.i += str.len() - 1;
|
|
||||||
|
|
||||||
match str.parse::<f64>() {
|
match str.parse::<f64>() {
|
||||||
Ok(n) => Ok(Some(JSONValue::Number(n))),
|
Ok(n) => {
|
||||||
Err(e) => Err(ParseError::ExpectedDigit(format!("{:#?}", (str, e)))),
|
self.increment(str.len() - 1);
|
||||||
|
return Ok(Some(JSONValue::Number(n)))
|
||||||
|
},
|
||||||
|
Err(e) => Err(ParseError::ExpectedDigit(format!("'{}', {:#?}", str, e))),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@ -342,7 +369,7 @@ impl JSON {
|
|||||||
/// error is returned
|
/// error is returned
|
||||||
fn eat(&mut self, ch: char) -> Result<(), ParseError> {
|
fn eat(&mut self, ch: char) -> Result<(), ParseError> {
|
||||||
if self.chars[self.i] != ch {
|
if self.chars[self.i] != ch {
|
||||||
let msg = format!("Expected '{}'.", ch);
|
let msg = format!("Expected {}.", ch);
|
||||||
return Err(ParseError::ExpectedToken(msg));
|
return Err(ParseError::ExpectedToken(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,6 +435,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_number() {
|
fn parse_number() {
|
||||||
|
// This function works like I think, right?
|
||||||
|
assert_ne!(','.is_ascii_digit(), true);
|
||||||
|
|
||||||
let mut parser = JSON::new(r#""foo""#);
|
let mut parser = JSON::new(r#""foo""#);
|
||||||
let res = JSON::parse_number(&mut parser);
|
let res = JSON::parse_number(&mut parser);
|
||||||
assert_eq!(res, Ok(None));
|
assert_eq!(res, Ok(None));
|
||||||
@ -419,6 +449,10 @@ mod tests {
|
|||||||
let mut parser = JSON::new("3e4");
|
let mut parser = JSON::new("3e4");
|
||||||
let res = JSON::parse_number(&mut parser);
|
let res = JSON::parse_number(&mut parser);
|
||||||
assert_eq!(res, Ok(Some(JSONValue::Number(3e4f64))));
|
assert_eq!(res, Ok(Some(JSONValue::Number(3e4f64))));
|
||||||
|
|
||||||
|
let mut parser = JSON::new("1.234,");
|
||||||
|
let res = JSON::parse_number(&mut parser);
|
||||||
|
assert_eq!(res, Ok(Some(JSONValue::Number(1.234f64))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -456,6 +490,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_parse_arbitrary_json() {
|
fn can_parse_arbitrary_json() {
|
||||||
|
let result = JSON::parse("[{}]");
|
||||||
|
assert_eq!(result, Ok(JSONValue::Array(vec![JSONValue::Object(HashMap::new())])));
|
||||||
|
|
||||||
let result = JSON::parse(
|
let result = JSON::parse(
|
||||||
r#"[{
|
r#"[{
|
||||||
"a": 9.38083151965,
|
"a": 9.38083151965,
|
||||||
@ -472,7 +509,6 @@ mod tests {
|
|||||||
"i": ["\"", "\\", "/", "\b", "\f", "\n", "\r", "\t", "\u0001", "\uface"]
|
"i": ["\"", "\\", "/", "\b", "\f", "\n", "\r", "\t", "\u0001", "\uface"]
|
||||||
}]"#,
|
}]"#,
|
||||||
);
|
);
|
||||||
// let msg = format!("{:#?}", result);
|
|
||||||
assert!(result.is_ok(), format!("{:#?}", result));
|
assert!(result.is_ok(), format!("{:#?}", result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user