diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/de.rs | 9 | ||||
-rw-r--r-- | src/ser.rs | 49 | ||||
-rw-r--r-- | src/tokens.rs | 4 |
3 files changed, 34 insertions, 28 deletions
@@ -6,6 +6,7 @@ use std::borrow::Cow; use std::error; +use std::f64; use std::fmt; use std::str; use std::vec; @@ -882,6 +883,14 @@ impl<'a> Deserializer<'a> { } _ => Err(self.error(at, ErrorKind::NumberInvalid)), } + } else if s == "inf" { + Ok(Value { e: E::Float(f64::INFINITY), start: start, end: end }) + } else if s == "-inf" { + Ok(Value { e: E::Float(f64::NEG_INFINITY), start: start, end: end }) + } else if s == "nan" { + Ok(Value { e: E::Float(f64::NAN), start: start, end: end }) + } else if s == "-nan" { + Ok(Value { e: E::Float(-f64::NAN), start: start, end: end }) } else { self.integer(s).map(|f| Value { e: E::Integer(f), start: start, end: end }) } @@ -737,6 +737,27 @@ impl<'a> Serializer<'a> { } } +macro_rules! serialize_float { + ($this:expr, $v:expr) => {{ + $this.emit_key("float")?; + if ($v.is_nan() || $v == 0.0) && $v.is_sign_negative() { + drop(write!($this.dst, "-")); + } + if $v.is_nan() { + drop(write!($this.dst, "nan")); + } else { + drop(write!($this.dst, "{}", $v)); + } + if $v % 1.0 == 0.0 { + drop(write!($this.dst, ".0")); + } + if let State::Table { .. } = $this.state { + $this.dst.push_str("\n"); + } + return Ok(()); + }}; +} + impl<'a, 'b> ser::Serializer for &'b mut Serializer<'a> { type Ok = (); type Error = Error; @@ -785,35 +806,11 @@ impl<'a, 'b> ser::Serializer for &'b mut Serializer<'a> { } fn serialize_f32(self, v: f32) -> Result<(), Self::Error> { - if !v.is_finite() { - return Err(Error::NumberInvalid); - } - - self.emit_key("float")?; - drop(write!(self.dst, "{}", v)); - if v % 1.0 == 0.0 { - drop(write!(self.dst, ".0")); - } - if let State::Table { .. } = self.state { - self.dst.push_str("\n"); - } - Ok(()) + serialize_float!(self, v) } fn serialize_f64(self, v: f64) -> Result<(), Self::Error> { - if !v.is_finite() { - return Err(Error::NumberInvalid); - } - - self.emit_key("float")?; - drop(write!(self.dst, "{}", v)); - if v % 1.0 == 0.0 { - drop(write!(self.dst, ".0")); - } - if let State::Table { .. } = self.state { - self.dst.push_str("\n"); - } - Ok(()) + serialize_float!(self, v) } fn serialize_char(self, v: char) -> Result<(), Self::Error> { diff --git a/src/tokens.rs b/src/tokens.rs index 1b5a755..79aeb60 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -331,7 +331,7 @@ impl<'a> Tokenizer<'a> { fn literal_string(&mut self, start: usize) -> Result<Token<'a>, Error> { self.read_string('\'', start, &mut |_me, val, _multi, i, ch| { - if ch == '\u{09}' || ('\u{20}' <= ch && ch <= '\u{10ffff}') { + if ch == '\u{09}' || ('\u{20}' <= ch && ch <= '\u{10ffff}' && ch != '\u{7f}') { val.push(ch); Ok(()) } else { @@ -373,7 +373,7 @@ impl<'a> Tokenizer<'a> { } Ok(()) } - ch if '\u{20}' <= ch && ch <= '\u{10ffff}' => { + ch if '\u{20}' <= ch && ch <= '\u{10ffff}' && ch != '\u{7f}' => { val.push(ch); Ok(()) } |