From ca4f53655e82a0a0e1d613b16108720bb7a50fde Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Mon, 24 Nov 2014 02:22:30 +0900 Subject: [PATCH 1/5] 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 #18319 [breaking-change] --- src/libserialize/json.rs | 43 +++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 248d78236ad..371034746fc 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -419,17 +419,17 @@ impl<'a> Encoder<'a> { impl<'a> ::Encoder for Encoder<'a> { fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } - fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) } - fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) } fn emit_bool(&mut self, v: bool) -> EncodeResult { if v { @@ -620,17 +620,17 @@ impl<'a> PrettyEncoder<'a> { impl<'a> ::Encoder for PrettyEncoder<'a> { fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } - fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) } - fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) } fn emit_bool(&mut self, v: bool) -> EncodeResult { if v { @@ -2500,6 +2500,9 @@ mod tests { assert_eq!(I64(-5678).to_string().into_string(), "-5678"); assert_eq!(I64(-5678).to_pretty_str().into_string(), "-5678"); + + assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); + assert_eq!(U64(7650007200025252000).to_pretty_str(), "7650007200025252000"); } #[test] From f102123b659911dbee25bbe518d73d66185bb978 Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Mon, 24 Nov 2014 03:00:10 +0900 Subject: [PATCH 2/5] libserialize: Do not coerce to integer when decoding a float value When an integral value is expected by the user but a fractional value is found, the current implementation uses std::num::cast() to coerce to an integer type, losing the fractional part. This behavior is not desirable because the number loses precision without notice. This commit makes it raise ExpectedError when such a situation arises. [breaking-change] --- src/libserialize/json.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 371034746fc..23e2c4b9830 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -1974,10 +1974,7 @@ macro_rules! read_primitive { } } Json::F64(f) => { - match num::cast(f) { - Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), format!("{}", f))), - } + Err(ExpectedError("Integer".to_string(), format!("{}", f))) } Json::String(s) => { // re: #12967.. a type w/ numeric keys (ie HashMap etc) @@ -2830,6 +2827,9 @@ mod tests { let v: i64 = super::decode("9223372036854775807").unwrap(); assert_eq!(v, i64::MAX); + + let res: DecodeResult = super::decode("765.25252"); + assert_eq!(res, Err(ExpectedError("Integer".into_string(), "765.25252".into_string()))); } #[test] From fec0f16c98ab066ff11be35b5a8bb0d80efa90f1 Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Mon, 24 Nov 2014 03:14:02 +0900 Subject: [PATCH 3/5] libserialize: Always use a decimal point when emitting a float value JSON doesn't distinguish between integer and float. They are just numbers. Also, in the current implementation, a fractional number without the fractional part is encoded without a decimal point. Thereforce, when the value is decoded, it is first rendered as Json, either I64 or U64. This reduces type safety, because while the original intention was to cast the value to float, it can also be casted to integer. As a workaround of this problem, this commit makes the encoder always emit a decimal point even if it is not necessary. If the fractional part of a float number is zero, ".0" is padded to the end of the result. [breaking-change] --- src/libserialize/json.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 23e2c4b9830..163fbcdff70 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -386,7 +386,8 @@ fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> { fn fmt_number_or_null(v: f64) -> string::String { match v.classify() { FPNaN | FPInfinite => string::String::from_str("null"), - _ => f64::to_str_digits(v, 6u) + _ if v.fract() != 0f64 => f64::to_str_digits(v, 6u), + _ => f64::to_str_digits(v, 6u) + ".0", } } @@ -2504,8 +2505,8 @@ mod tests { #[test] fn test_write_f64() { - assert_eq!(F64(3.0).to_string().into_string(), "3"); - assert_eq!(F64(3.0).to_pretty_str().into_string(), "3"); + assert_eq!(F64(3.0).to_string().into_string(), "3.0"); + assert_eq!(F64(3.0).to_pretty_str().into_string(), "3.0"); assert_eq!(F64(3.1).to_string().into_string(), "3.1"); assert_eq!(F64(3.1).to_pretty_str().into_string(), "3.1"); From c32286d1b1f1494cf46fb6403e329e7bb6d31942 Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Mon, 24 Nov 2014 03:32:31 +0900 Subject: [PATCH 4/5] libserialize: Code cleanup --- src/libserialize/json.rs | 134 +++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 69 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 163fbcdff70..533ec38f678 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -91,7 +91,7 @@ //! fn main() { //! let object = TestStruct { //! data_int: 1, -//! data_str: "toto".to_string(), +//! data_str: "homura".to_string(), //! data_vector: vec![2,3,4,5], //! }; //! @@ -178,7 +178,7 @@ //! // Serialize using `ToJson` //! let input_data = TestStruct { //! data_int: 1, -//! data_str: "toto".to_string(), +//! data_str: "madoka".to_string(), //! data_vector: vec![2,3,4,5], //! }; //! let json_obj: Json = input_data.to_json(); @@ -443,7 +443,9 @@ impl<'a> ::Encoder for Encoder<'a> { fn emit_f64(&mut self, v: f64) -> EncodeResult { write!(self.writer, "{}", fmt_number_or_null(v)) } - fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_f32(&mut self, v: f32) -> EncodeResult { + self.emit_f64(v as f64) + } fn emit_char(&mut self, v: char) -> EncodeResult { escape_char(self.writer, v) @@ -452,7 +454,9 @@ impl<'a> ::Encoder for Encoder<'a> { escape_str(self.writer, v) } - fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum(&mut self, + _name: &str, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { f(self) } @@ -663,7 +667,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { fn emit_enum_variant(&mut self, name: &str, - _: uint, + _id: uint, cnt: uint, f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if cnt == 0 { @@ -1962,30 +1966,22 @@ macro_rules! read_primitive { ($name:ident, $ty:ty) => { fn $name(&mut self) -> DecodeResult<$ty> { match self.pop() { - Json::I64(f) => { - match num::cast(f) { - Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), format!("{}", f))), - } - } - Json::U64(f) => { - match num::cast(f) { - Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), format!("{}", f))), - } - } - Json::F64(f) => { - Err(ExpectedError("Integer".to_string(), format!("{}", f))) - } - Json::String(s) => { - // re: #12967.. a type w/ numeric keys (ie HashMap etc) - // is going to have a string here, as per JSON spec. - match std::str::from_str(s.as_slice()) { - Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), s)), - } + Json::I64(f) => match num::cast(f) { + Some(f) => Ok(f), + None => Err(ExpectedError("Number".to_string(), format!("{}", f))), }, - value => Err(ExpectedError("Number".to_string(), format!("{}", value))) + Json::U64(f) => match num::cast(f) { + Some(f) => Ok(f), + None => Err(ExpectedError("Number".to_string(), format!("{}", f))), + }, + Json::F64(f) => Err(ExpectedError("Integer".to_string(), format!("{}", f))), + // re: #12967.. a type w/ numeric keys (ie HashMap etc) + // is going to have a string here, as per JSON spec. + Json::String(s) => match std::str::from_str(s.as_slice()) { + Some(f) => Ok(f), + None => Err(ExpectedError("Number".to_string(), s)), + }, + value => Err(ExpectedError("Number".to_string(), format!("{}", value))), } } } @@ -2484,20 +2480,20 @@ mod tests { #[test] fn test_write_null() { - assert_eq!(Null.to_string().into_string(), "null"); - assert_eq!(Null.to_pretty_str().into_string(), "null"); + assert_eq!(Null.to_string(), "null"); + assert_eq!(Null.to_pretty_str(), "null"); } #[test] fn test_write_i64() { - assert_eq!(U64(0).to_string().into_string(), "0"); - assert_eq!(U64(0).to_pretty_str().into_string(), "0"); + assert_eq!(U64(0).to_string(), "0"); + assert_eq!(U64(0).to_pretty_str(), "0"); - assert_eq!(U64(1234).to_string().into_string(), "1234"); - assert_eq!(U64(1234).to_pretty_str().into_string(), "1234"); + assert_eq!(U64(1234).to_string(), "1234"); + assert_eq!(U64(1234).to_pretty_str(), "1234"); - assert_eq!(I64(-5678).to_string().into_string(), "-5678"); - assert_eq!(I64(-5678).to_pretty_str().into_string(), "-5678"); + assert_eq!(I64(-5678).to_string(), "-5678"); + assert_eq!(I64(-5678).to_pretty_str(), "-5678"); assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); assert_eq!(U64(7650007200025252000).to_pretty_str(), "7650007200025252000"); @@ -2505,54 +2501,54 @@ mod tests { #[test] fn test_write_f64() { - assert_eq!(F64(3.0).to_string().into_string(), "3.0"); - assert_eq!(F64(3.0).to_pretty_str().into_string(), "3.0"); + assert_eq!(F64(3.0).to_string(), "3.0"); + assert_eq!(F64(3.0).to_pretty_str(), "3.0"); - assert_eq!(F64(3.1).to_string().into_string(), "3.1"); - assert_eq!(F64(3.1).to_pretty_str().into_string(), "3.1"); + assert_eq!(F64(3.1).to_string(), "3.1"); + assert_eq!(F64(3.1).to_pretty_str(), "3.1"); - assert_eq!(F64(-1.5).to_string().into_string(), "-1.5"); - assert_eq!(F64(-1.5).to_pretty_str().into_string(), "-1.5"); + assert_eq!(F64(-1.5).to_string(), "-1.5"); + assert_eq!(F64(-1.5).to_pretty_str(), "-1.5"); - assert_eq!(F64(0.5).to_string().into_string(), "0.5"); - assert_eq!(F64(0.5).to_pretty_str().into_string(), "0.5"); + assert_eq!(F64(0.5).to_string(), "0.5"); + assert_eq!(F64(0.5).to_pretty_str(), "0.5"); - assert_eq!(F64(f64::NAN).to_string().into_string(), "null"); - assert_eq!(F64(f64::NAN).to_pretty_str().into_string(), "null"); + assert_eq!(F64(f64::NAN).to_string(), "null"); + assert_eq!(F64(f64::NAN).to_pretty_str(), "null"); - assert_eq!(F64(f64::INFINITY).to_string().into_string(), "null"); - assert_eq!(F64(f64::INFINITY).to_pretty_str().into_string(), "null"); + assert_eq!(F64(f64::INFINITY).to_string(), "null"); + assert_eq!(F64(f64::INFINITY).to_pretty_str(), "null"); - assert_eq!(F64(f64::NEG_INFINITY).to_string().into_string(), "null"); - assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str().into_string(), "null"); + assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null"); + assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str(), "null"); } #[test] fn test_write_str() { - assert_eq!(String("".to_string()).to_string().into_string(), "\"\""); - assert_eq!(String("".to_string()).to_pretty_str().into_string(), "\"\""); + assert_eq!(String("".to_string()).to_string(), "\"\""); + assert_eq!(String("".to_string()).to_pretty_str(), "\"\""); - assert_eq!(String("foo".to_string()).to_string().into_string(), "\"foo\""); - assert_eq!(String("foo".to_string()).to_pretty_str().into_string(), "\"foo\""); + assert_eq!(String("homura".to_string()).to_string(), "\"homura\""); + assert_eq!(String("madoka".to_string()).to_pretty_str(), "\"madoka\""); } #[test] fn test_write_bool() { - assert_eq!(Boolean(true).to_string().into_string(), "true"); - assert_eq!(Boolean(true).to_pretty_str().into_string(), "true"); + assert_eq!(Boolean(true).to_string(), "true"); + assert_eq!(Boolean(true).to_pretty_str(), "true"); - assert_eq!(Boolean(false).to_string().into_string(), "false"); - assert_eq!(Boolean(false).to_pretty_str().into_string(), "false"); + assert_eq!(Boolean(false).to_string(), "false"); + assert_eq!(Boolean(false).to_pretty_str(), "false"); } #[test] fn test_write_array() { - assert_eq!(Array(vec![]).to_string().into_string(), "[]"); - assert_eq!(Array(vec![]).to_pretty_str().into_string(), "[]"); + assert_eq!(Array(vec![]).to_string(), "[]"); + assert_eq!(Array(vec![]).to_pretty_str(), "[]"); - assert_eq!(Array(vec![Boolean(true)]).to_string().into_string(), "[true]"); + assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]"); assert_eq!( - Array(vec![Boolean(true)]).to_pretty_str().into_string(), + Array(vec![Boolean(true)]).to_pretty_str(), "\ [\n \ true\n\ @@ -2564,10 +2560,10 @@ mod tests { Null, Array(vec![String("foo\nbar".to_string()), F64(3.5)])]); - assert_eq!(long_test_array.to_string().into_string(), + assert_eq!(long_test_array.to_string(), "[false,null,[\"foo\\nbar\",3.5]]"); assert_eq!( - long_test_array.to_pretty_str().into_string(), + long_test_array.to_pretty_str(), "\ [\n \ false,\n \ @@ -2582,13 +2578,13 @@ mod tests { #[test] fn test_write_object() { - assert_eq!(mk_object(&[]).to_string().into_string(), "{}"); - assert_eq!(mk_object(&[]).to_pretty_str().into_string(), "{}"); + assert_eq!(mk_object(&[]).to_string(), "{}"); + assert_eq!(mk_object(&[]).to_pretty_str(), "{}"); assert_eq!( mk_object(&[ ("a".to_string(), Boolean(true)) - ]).to_string().into_string(), + ]).to_string(), "{\"a\":true}" ); assert_eq!( @@ -2607,7 +2603,7 @@ mod tests { ]); assert_eq!( - complex_obj.to_string().into_string(), + complex_obj.to_string(), "{\ \"b\":[\ {\"c\":\"\\f\\r\"},\ @@ -2616,7 +2612,7 @@ mod tests { }" ); assert_eq!( - complex_obj.to_pretty_str().into_string(), + complex_obj.to_pretty_str(), "\ {\n \ \"b\": [\n \ From 7176dd1c9039d7d10c0ceb694b929d094cc299e3 Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Mon, 8 Dec 2014 18:16:09 +0900 Subject: [PATCH 5/5] libserialize: Prefer into_string() to to_string() wherever possible Except for the example code! --- src/libserialize/json.rs | 170 +++++++++++++++++++-------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 533ec38f678..74fd2bcfbd9 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -1947,7 +1947,7 @@ macro_rules! expect( ($e:expr, Null) => ({ match $e { Json::Null => Ok(()), - other => Err(ExpectedError("Null".to_string(), + other => Err(ExpectedError("Null".into_string(), format!("{}", other))) } }); @@ -1968,20 +1968,20 @@ macro_rules! read_primitive { match self.pop() { Json::I64(f) => match num::cast(f) { Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), format!("{}", f))), + None => Err(ExpectedError("Number".into_string(), format!("{}", f))), }, Json::U64(f) => match num::cast(f) { Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), format!("{}", f))), + None => Err(ExpectedError("Number".into_string(), format!("{}", f))), }, - Json::F64(f) => Err(ExpectedError("Integer".to_string(), format!("{}", f))), + Json::F64(f) => Err(ExpectedError("Integer".into_string(), format!("{}", f))), // re: #12967.. a type w/ numeric keys (ie HashMap etc) // is going to have a string here, as per JSON spec. Json::String(s) => match std::str::from_str(s.as_slice()) { Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), s)), + None => Err(ExpectedError("Number".into_string(), s)), }, - value => Err(ExpectedError("Number".to_string(), format!("{}", value))), + value => Err(ExpectedError("Number".into_string(), format!("{}", value))), } } } @@ -2017,11 +2017,11 @@ impl ::Decoder for Decoder { // is going to have a string here, as per JSON spec. match std::str::from_str(s.as_slice()) { Some(f) => Ok(f), - None => Err(ExpectedError("Number".to_string(), s)), + None => Err(ExpectedError("Number".into_string(), s)), } }, Json::Null => Ok(f64::NAN), - value => Err(ExpectedError("Number".to_string(), format!("{}", value))) + value => Err(ExpectedError("Number".into_string(), format!("{}", value))) } } @@ -2040,7 +2040,7 @@ impl ::Decoder for Decoder { _ => () } } - Err(ExpectedError("single character string".to_string(), format!("{}", s))) + Err(ExpectedError("single character string".into_string(), format!("{}", s))) } fn read_str(&mut self) -> DecodeResult { @@ -2063,32 +2063,32 @@ impl ::Decoder for Decoder { let name = match self.pop() { Json::String(s) => s, Json::Object(mut o) => { - let n = match o.remove(&"variant".to_string()) { + let n = match o.remove(&"variant".into_string()) { Some(Json::String(s)) => s, Some(val) => { - return Err(ExpectedError("String".to_string(), format!("{}", val))) + return Err(ExpectedError("String".into_string(), format!("{}", val))) } None => { - return Err(MissingFieldError("variant".to_string())) + return Err(MissingFieldError("variant".into_string())) } }; - match o.remove(&"fields".to_string()) { + match o.remove(&"fields".into_string()) { Some(Json::Array(l)) => { for field in l.into_iter().rev() { self.stack.push(field); } }, Some(val) => { - return Err(ExpectedError("Array".to_string(), format!("{}", val))) + return Err(ExpectedError("Array".into_string(), format!("{}", val))) } None => { - return Err(MissingFieldError("fields".to_string())) + return Err(MissingFieldError("fields".into_string())) } } n } json => { - return Err(ExpectedError("String or Object".to_string(), format!("{}", json))) + return Err(ExpectedError("String or Object".into_string(), format!("{}", json))) } }; let idx = match names.iter() @@ -2437,9 +2437,9 @@ mod tests { #[test] fn test_decode_option_malformed() { check_err::("{ \"opt\": [] }", - ExpectedError("Number".to_string(), "[]".to_string())); + ExpectedError("Number".into_string(), "[]".into_string())); check_err::("{ \"opt\": false }", - ExpectedError("Number".to_string(), "false".to_string())); + ExpectedError("Number".into_string(), "false".into_string())); } #[deriving(PartialEq, Encodable, Decodable, Show)] @@ -2525,11 +2525,11 @@ mod tests { #[test] fn test_write_str() { - assert_eq!(String("".to_string()).to_string(), "\"\""); - assert_eq!(String("".to_string()).to_pretty_str(), "\"\""); + assert_eq!(String("".into_string()).to_string(), "\"\""); + assert_eq!(String("".into_string()).to_pretty_str(), "\"\""); - assert_eq!(String("homura".to_string()).to_string(), "\"homura\""); - assert_eq!(String("madoka".to_string()).to_pretty_str(), "\"madoka\""); + assert_eq!(String("homura".into_string()).to_string(), "\"homura\""); + assert_eq!(String("madoka".into_string()).to_pretty_str(), "\"madoka\""); } #[test] @@ -2558,7 +2558,7 @@ mod tests { let long_test_array = Array(vec![ Boolean(false), Null, - Array(vec![String("foo\nbar".to_string()), F64(3.5)])]); + Array(vec![String("foo\nbar".into_string()), F64(3.5)])]); assert_eq!(long_test_array.to_string(), "[false,null,[\"foo\\nbar\",3.5]]"); @@ -2583,12 +2583,12 @@ mod tests { assert_eq!( mk_object(&[ - ("a".to_string(), Boolean(true)) + ("a".into_string(), Boolean(true)) ]).to_string(), "{\"a\":true}" ); assert_eq!( - mk_object(&[("a".to_string(), Boolean(true))]).to_pretty_str(), + mk_object(&[("a".into_string(), Boolean(true))]).to_pretty_str(), "\ {\n \ \"a\": true\n\ @@ -2596,9 +2596,9 @@ mod tests { ); let complex_obj = mk_object(&[ - ("b".to_string(), Array(vec![ - mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), - mk_object(&[("d".to_string(), String("".to_string()))]) + ("b".into_string(), Array(vec![ + mk_object(&[("c".into_string(), String("\x0c\r".into_string()))]), + mk_object(&[("d".into_string(), String("".into_string()))]) ])) ]); @@ -2627,10 +2627,10 @@ mod tests { ); let a = mk_object(&[ - ("a".to_string(), Boolean(true)), - ("b".to_string(), Array(vec![ - mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), - mk_object(&[("d".to_string(), String("".to_string()))]) + ("a".into_string(), Boolean(true)), + ("b".into_string(), Array(vec![ + mk_object(&[("c".into_string(), String("\x0c\r".into_string()))]), + mk_object(&[("d".into_string(), String("".into_string()))]) ])) ]); @@ -2667,7 +2667,7 @@ mod tests { "\"Dog\"" ); - let animal = Frog("Henry".to_string(), 349); + let animal = Frog("Henry".into_string(), 349); assert_eq!( with_str_writer(|writer| { let mut encoder = Encoder::new(writer); @@ -2692,14 +2692,14 @@ mod tests { #[test] fn test_write_some() { - let value = Some("jodhpurs".to_string()); + let value = Some("jodhpurs".into_string()); let s = with_str_writer(|writer| { let mut encoder = Encoder::new(writer); value.encode(&mut encoder).unwrap(); }); assert_eq!(s, "\"jodhpurs\""); - let value = Some("jodhpurs".to_string()); + let value = Some("jodhpurs".into_string()); let s = with_str_writer(|writer| { let mut encoder = PrettyEncoder::new(writer); value.encode(&mut encoder).unwrap(); @@ -2834,16 +2834,16 @@ mod tests { assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2))); assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5))); - assert_eq!(from_str("\"\""), Ok(String("".to_string()))); - assert_eq!(from_str("\"foo\""), Ok(String("foo".to_string()))); - assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_string()))); - assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_string()))); - assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_string()))); - assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_string()))); - assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_string()))); - assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_string()))); - assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".to_string()))); - assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".to_string()))); + assert_eq!(from_str("\"\""), Ok(String("".into_string()))); + assert_eq!(from_str("\"foo\""), Ok(String("foo".into_string()))); + assert_eq!(from_str("\"\\\"\""), Ok(String("\"".into_string()))); + assert_eq!(from_str("\"\\b\""), Ok(String("\x08".into_string()))); + assert_eq!(from_str("\"\\n\""), Ok(String("\n".into_string()))); + assert_eq!(from_str("\"\\r\""), Ok(String("\r".into_string()))); + assert_eq!(from_str("\"\\t\""), Ok(String("\t".into_string()))); + assert_eq!(from_str(" \"foo\" "), Ok(String("foo".into_string()))); + assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".into_string()))); + assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".into_string()))); } #[test] @@ -2909,7 +2909,7 @@ mod tests { assert_eq!(t, (1u, 2, 3)) let t: (uint, string::String) = super::decode("[1, \"two\"]").unwrap(); - assert_eq!(t, (1u, "two".to_string())); + assert_eq!(t, (1u, "two".into_string())); } #[test] @@ -2939,22 +2939,22 @@ mod tests { assert_eq!(from_str("{}").unwrap(), mk_object(&[])); assert_eq!(from_str("{\"a\": 3}").unwrap(), - mk_object(&[("a".to_string(), U64(3))])); + mk_object(&[("a".into_string(), U64(3))])); assert_eq!(from_str( "{ \"a\": null, \"b\" : true }").unwrap(), mk_object(&[ - ("a".to_string(), Null), - ("b".to_string(), Boolean(true))])); + ("a".into_string(), Null), + ("b".into_string(), Boolean(true))])); assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(), mk_object(&[ - ("a".to_string(), Null), - ("b".to_string(), Boolean(true))])); + ("a".into_string(), Null), + ("b".into_string(), Boolean(true))])); assert_eq!(from_str( "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), mk_object(&[ - ("a".to_string(), F64(1.0)), - ("b".to_string(), Array(vec![Boolean(true)])) + ("a".into_string(), F64(1.0)), + ("b".into_string(), Array(vec![Boolean(true)])) ])); assert_eq!(from_str( "{\ @@ -2966,12 +2966,12 @@ mod tests { ]\ }").unwrap(), mk_object(&[ - ("a".to_string(), F64(1.0)), - ("b".to_string(), Array(vec![ + ("a".into_string(), F64(1.0)), + ("b".into_string(), Array(vec![ Boolean(true), - String("foo\nbar".to_string()), + String("foo\nbar".into_string()), mk_object(&[ - ("c".to_string(), mk_object(&[("d".to_string(), Null)])) + ("c".into_string(), mk_object(&[("d".into_string(), Null)])) ]) ])) ])); @@ -2990,7 +2990,7 @@ mod tests { v, Outer { inner: vec![ - Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } + Inner { a: (), b: 2, c: vec!["abc".into_string(), "xyz".into_string()] } ] } ); @@ -3016,7 +3016,7 @@ mod tests { assert_eq!(value, None); let value: Option = super::decode("\"jodhpurs\"").unwrap(); - assert_eq!(value, Some("jodhpurs".to_string())); + assert_eq!(value, Some("jodhpurs".into_string())); } #[test] @@ -3026,7 +3026,7 @@ mod tests { let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; let value: Animal = super::decode(s).unwrap(); - assert_eq!(value, Frog("Henry".to_string(), 349)); + assert_eq!(value, Frog("Henry".into_string(), 349)); } #[test] @@ -3035,8 +3035,8 @@ mod tests { \"fields\":[\"Henry\", 349]}}"; let mut map: TreeMap = super::decode(s).unwrap(); - assert_eq!(map.remove(&"a".to_string()), Some(Dog)); - assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); + assert_eq!(map.remove(&"a".into_string()), Some(Dog)); + assert_eq!(map.remove(&"b".into_string()), Some(Frog("Henry".into_string(), 349))); } #[test] @@ -3076,30 +3076,30 @@ mod tests { } #[test] fn test_decode_errors_struct() { - check_err::("[]", ExpectedError("Object".to_string(), "[]".to_string())); + check_err::("[]", ExpectedError("Object".into_string(), "[]".into_string())); check_err::("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", - ExpectedError("Number".to_string(), "true".to_string())); + ExpectedError("Number".into_string(), "true".into_string())); check_err::("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", - ExpectedError("Boolean".to_string(), "[]".to_string())); + ExpectedError("Boolean".into_string(), "[]".into_string())); check_err::("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", - ExpectedError("String".to_string(), "{}".to_string())); + ExpectedError("String".into_string(), "{}".into_string())); check_err::("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", - ExpectedError("Array".to_string(), "null".to_string())); + ExpectedError("Array".into_string(), "null".into_string())); check_err::("{\"x\": 1, \"y\": true, \"z\": \"\"}", - MissingFieldError("w".to_string())); + MissingFieldError("w".into_string())); } #[test] fn test_decode_errors_enum() { check_err::("{}", - MissingFieldError("variant".to_string())); + MissingFieldError("variant".into_string())); check_err::("{\"variant\": 1}", - ExpectedError("String".to_string(), "1".to_string())); + ExpectedError("String".into_string(), "1".into_string())); check_err::("{\"variant\": \"A\"}", - MissingFieldError("fields".to_string())); + MissingFieldError("fields".into_string())); check_err::("{\"variant\": \"A\", \"fields\": null}", - ExpectedError("Array".to_string(), "null".to_string())); + ExpectedError("Array".into_string(), "null".into_string())); check_err::("{\"variant\": \"C\", \"fields\": []}", - UnknownVariantError("C".to_string())); + UnknownVariantError("C".into_string())); } #[test] @@ -3384,7 +3384,7 @@ mod tests { }; let mut decoder = Decoder::new(json_obj); let result: Result, DecoderError> = Decodable::decode(&mut decoder); - assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string()))); + assert_eq!(result, Err(ExpectedError("Number".into_string(), "a".into_string()))); } fn assert_stream_equal(src: &str, @@ -3411,7 +3411,7 @@ mod tests { r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#, vec![ (ObjectStart, vec![]), - (StringValue("bar".to_string()), vec![Key("foo")]), + (StringValue("bar".into_string()), vec![Key("foo")]), (ArrayStart, vec![Key("array")]), (U64Value(0), vec![Key("array"), Index(0)]), (U64Value(1), vec![Key("array"), Index(1)]), @@ -3502,7 +3502,7 @@ mod tests { (F64Value(1.0), vec![Key("a")]), (ArrayStart, vec![Key("b")]), (BooleanValue(true), vec![Key("b"), Index(0)]), - (StringValue("foo\nbar".to_string()), vec![Key("b"), Index(1)]), + (StringValue("foo\nbar".into_string()), vec![Key("b"), Index(1)]), (ObjectStart, vec![Key("b"), Index(2)]), (ObjectStart, vec![Key("b"), Index(2), Key("c")]), (NullValue, vec![Key("b"), Index(2), Key("c"), Key("d")]), @@ -3635,7 +3635,7 @@ mod tests { assert!(stack.last_is_index()); assert!(stack.get(0) == Index(1)); - stack.push_key("foo".to_string()); + stack.push_key("foo".into_string()); assert!(stack.len() == 2); assert!(stack.is_equal_to(&[Index(1), Key("foo")])); @@ -3647,7 +3647,7 @@ mod tests { assert!(stack.get(0) == Index(1)); assert!(stack.get(1) == Key("foo")); - stack.push_key("bar".to_string()); + stack.push_key("bar".into_string()); assert!(stack.len() == 3); assert!(stack.is_equal_to(&[Index(1), Key("foo"), Key("bar")])); @@ -3684,8 +3684,8 @@ mod tests { let array3 = Array(vec!(U64(1), U64(2), U64(3))); let object = { let mut tree_map = TreeMap::new(); - tree_map.insert("a".to_string(), U64(1)); - tree_map.insert("b".to_string(), U64(2)); + tree_map.insert("a".into_string(), U64(1)); + tree_map.insert("b".into_string(), U64(2)); Object(tree_map) }; @@ -3717,12 +3717,12 @@ mod tests { assert_eq!((vec![1u, 2]).to_json(), array2); assert_eq!(vec!(1u, 2, 3).to_json(), array3); let mut tree_map = TreeMap::new(); - tree_map.insert("a".to_string(), 1u); - tree_map.insert("b".to_string(), 2); + tree_map.insert("a".into_string(), 1u); + tree_map.insert("b".into_string(), 2); assert_eq!(tree_map.to_json(), object); let mut hash_map = HashMap::new(); - hash_map.insert("a".to_string(), 1u); - hash_map.insert("b".to_string(), 2); + hash_map.insert("a".into_string(), 1u); + hash_map.insert("b".into_string(), 2); assert_eq!(hash_map.to_json(), object); assert_eq!(Some(15i).to_json(), I64(15)); assert_eq!(Some(15u).to_json(), U64(15)); @@ -3765,7 +3765,7 @@ mod tests { } fn big_json() -> string::String { - let mut src = "[\n".to_string(); + let mut src = "[\n".into_string(); for _ in range(0i, 500) { src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \ [1,2,3]},"#);