Eliminate some code duplication parsing an exponent as an integer

This commit is contained in:
Erick Tryzelaar
2015-08-01 13:40:28 -07:00
parent fa562d449d
commit 8eff38b6f6
2 changed files with 37 additions and 26 deletions
+26 -23
View File
@@ -222,17 +222,20 @@ impl<Iter> Deserializer<Iter>
Ok(accum) Ok(accum)
} }
fn parse_decimal(&mut self, res: f64) -> Result<f64> { fn parse_decimal(&mut self, mut res: f64) -> Result<f64> {
try!(self.bump()); try!(self.bump());
let mut dec = 0.1;
// Make sure a digit follows the decimal place. // Make sure a digit follows the decimal place.
match self.ch_or_null() { match self.ch_or_null() {
b'0' ... b'9' => (), c @ b'0' ... b'9' => {
try!(self.bump());
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
}
_ => { return Err(self.error(ErrorCode::InvalidNumber)); } _ => { return Err(self.error(ErrorCode::InvalidNumber)); }
} }
let mut res = res;
let mut dec = 1.0;
while !self.eof() { while !self.eof() {
match self.ch_or_null() { match self.ch_or_null() {
c @ b'0' ... b'9' => { c @ b'0' ... b'9' => {
@@ -250,30 +253,30 @@ impl<Iter> Deserializer<Iter>
fn parse_exponent(&mut self, mut res: f64) -> Result<f64> { fn parse_exponent(&mut self, mut res: f64) -> Result<f64> {
try!(self.bump()); try!(self.bump());
let mut exp: u64 = 0; let pos = match self.ch_or_null() {
let mut neg_exp = false; b'+' => { try!(self.bump()); true }
b'-' => { try!(self.bump()); false }
if self.ch_is(b'+') { _ => { true }
try!(self.bump()); };
} else if self.ch_is(b'-') {
try!(self.bump());
neg_exp = true;
}
// Make sure a digit follows the exponent place. // Make sure a digit follows the exponent place.
match self.ch_or_null() { let mut exp = match self.ch_or_null() {
b'0' ... b'9' => (), c @ b'0' ... b'9' => {
try!(self.bump());
(c as u64) - (b'0' as u64)
}
_ => { return Err(self.error(ErrorCode::InvalidNumber)); } _ => { return Err(self.error(ErrorCode::InvalidNumber)); }
} };
while !self.eof() {
loop {
match self.ch_or_null() { match self.ch_or_null() {
c @ b'0' ... b'9' => { c @ b'0' ... b'9' => {
try!(self.bump());
exp = try_or_invalid!(self, exp.checked_mul(10)); exp = try_or_invalid!(self, exp.checked_mul(10));
exp = try_or_invalid!(self, exp.checked_add((c as u64) - (b'0' as u64))); exp = try_or_invalid!(self, exp.checked_add((c as u64) - (b'0' as u64)));
try!(self.bump());
} }
_ => break _ => { break; }
} }
} }
@@ -283,10 +286,10 @@ impl<Iter> Deserializer<Iter>
return Err(self.error(ErrorCode::InvalidNumber)); return Err(self.error(ErrorCode::InvalidNumber));
}; };
if neg_exp { if pos {
res /= exp;
} else {
res *= exp; res *= exp;
} else {
res /= exp;
} }
Ok(res) Ok(res)
+11 -3
View File
@@ -708,7 +708,7 @@ fn test_parse_number_errors() {
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)), ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
("777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 20)), ("777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 20)),
("1e777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 22)), ("1e777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 23)),
]); ]);
} }
@@ -735,13 +735,21 @@ fn test_parse_f64() {
test_parse_ok(vec![ test_parse_ok(vec![
("0.0", 0.0f64), ("0.0", 0.0f64),
("3.0", 3.0f64), ("3.0", 3.0f64),
("3.00", 3.0f64),
("3.1", 3.1), ("3.1", 3.1),
("-1.2", -1.2), ("-1.2", -1.2),
("0.4", 0.4), ("0.4", 0.4),
("0.4e5", 0.4e5), ("0.4e5", 0.4e5),
("0.4e+5", 0.4e5),
("0.4e15", 0.4e15), ("0.4e15", 0.4e15),
("0.4e-01", 0.4e-01), ("0.4e+15", 0.4e15),
(" 0.4e-01 ", 0.4e-01), ("0.4e-01", 0.4e-1),
(" 0.4e-01 ", 0.4e-1),
("0.4e-001", 0.4e-1),
("0.4e-0", 0.4e0),
("0.00e00", 0.0),
("0.00e+00", 0.0),
("0.00e-00", 0.0),
]); ]);
} }