Skip to content

Commit 4b6700b

Browse files
ryan-summerseldruin
authored andcommitted
Adding support for deserializing floats without termination
1 parent fd8647a commit 4b6700b

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

src/de/mod.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -312,23 +312,22 @@ macro_rules! deserialize_signed {
312312
macro_rules! deserialize_fromstr {
313313
($self:ident, $visitor:ident, $typ:ident, $visit_fn:ident, $pattern:expr) => {{
314314
let start = $self.index;
315-
loop {
316-
match $self.peek() {
317-
Some(c) => {
318-
if $pattern.iter().find(|&&d| d == c).is_some() {
319-
$self.eat_char();
320-
} else {
321-
let s = unsafe {
322-
// already checked that it contains only ascii
323-
str::from_utf8_unchecked(&$self.slice[start..$self.index])
324-
};
325-
let v = $typ::from_str(s).or(Err(Error::InvalidNumber))?;
326-
return $visitor.$visit_fn(v);
327-
}
328-
}
329-
None => return Err(Error::EofWhileParsingNumber),
315+
while $self.peek().is_some() {
316+
let c = $self.peek().unwrap();
317+
if $pattern.iter().find(|&&d| d == c).is_some() {
318+
$self.eat_char();
319+
} else {
320+
break;
330321
}
331322
}
323+
324+
// Note(unsafe): We already checked that it only contains ascii. This is only true if the
325+
// caller has guaranteed that `pattern` contains only ascii characters.
326+
let s = unsafe { str::from_utf8_unchecked(&$self.slice[start..$self.index]) };
327+
328+
let v = $typ::from_str(s).or(Err(Error::InvalidNumber))?;
329+
330+
$visitor.$visit_fn(v)
332331
}};
333332
}
334333

@@ -784,6 +783,24 @@ mod tests {
784783
assert!(crate::from_str::<bool>("tru").is_err());
785784
}
786785

786+
#[test]
787+
fn floating_point() {
788+
assert_eq!(crate::from_str("5.0"), Ok((5.0, 3)));
789+
assert_eq!(crate::from_str("1"), Ok((1.0, 1)));
790+
assert_eq!(crate::from_str("1e5"), Ok((1e5, 3)));
791+
assert!(crate::from_str::<f32>("a").is_err());
792+
assert!(crate::from_str::<f32>(",").is_err());
793+
}
794+
795+
#[test]
796+
fn integer() {
797+
assert_eq!(crate::from_str("5"), Ok((5, 1)));
798+
assert_eq!(crate::from_str("101"), Ok((101, 3)));
799+
assert!(crate::from_str::<u16>("1e5").is_err());
800+
assert!(crate::from_str::<u8>("256").is_err());
801+
assert!(crate::from_str::<f32>(",").is_err());
802+
}
803+
787804
#[test]
788805
fn enum_clike() {
789806
assert_eq!(crate::from_str(r#" "boolean" "#), Ok((Type::Boolean, 11)));

0 commit comments

Comments
 (0)