Skip to content

Commit ca4f536

Browse files
committed
libserialize: Remove float preprocessing in serialize::json::Encoder
serialize::json::Encoder currently uses f64 to emit any integral type. This is possibly due to the behavior of JavaScript, which uses f64 to represent any numeric value. This leads to a problem that only the integers in the range of [-2^53+1, 2^53-1] can be encoded. Therefore, i64 and u64 cannot be used reliably in the current implementation. RFC 7159 suggests that good interoperability can be achieved if the range is respected by implementations. However, it also says that implementations are allowed to set the range of number accepted. And it seems that the JSON encoders outside of the JavaScript world usually make use of i64 values. This commit removes the float preprocessing done in the emit_* methods. It also increases performance, because transforming f64 into String costs more than that of an integral type. Fixes rust-lang#18319 [breaking-change]
1 parent 83a44c7 commit ca4f536

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

src/libserialize/json.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -419,17 +419,17 @@ impl<'a> Encoder<'a> {
419419
impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
420420
fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
421421

422-
fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) }
423-
fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) }
424-
fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) }
425-
fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) }
426-
fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) }
427-
428-
fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) }
429-
fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) }
430-
fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) }
431-
fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) }
432-
fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) }
422+
fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
423+
fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) }
424+
fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) }
425+
fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) }
426+
fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) }
427+
428+
fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) }
429+
fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) }
430+
fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) }
431+
fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) }
432+
fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) }
433433

434434
fn emit_bool(&mut self, v: bool) -> EncodeResult {
435435
if v {
@@ -620,17 +620,17 @@ impl<'a> PrettyEncoder<'a> {
620620
impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
621621
fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
622622

623-
fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) }
624-
fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) }
625-
fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) }
626-
fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) }
627-
fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) }
623+
fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
624+
fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) }
625+
fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) }
626+
fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) }
627+
fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) }
628628

629-
fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) }
630-
fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) }
631-
fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) }
632-
fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) }
633-
fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) }
629+
fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) }
630+
fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) }
631+
fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) }
632+
fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) }
633+
fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) }
634634

635635
fn emit_bool(&mut self, v: bool) -> EncodeResult {
636636
if v {
@@ -2500,6 +2500,9 @@ mod tests {
25002500

25012501
assert_eq!(I64(-5678).to_string().into_string(), "-5678");
25022502
assert_eq!(I64(-5678).to_pretty_str().into_string(), "-5678");
2503+
2504+
assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000");
2505+
assert_eq!(U64(7650007200025252000).to_pretty_str(), "7650007200025252000");
25032506
}
25042507

25052508
#[test]

0 commit comments

Comments
 (0)