From 85b80aa1e1c69f0ee22c93e7126f96ab7182377a Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 23 Jan 2015 10:52:58 +0100 Subject: [PATCH 1/2] don't ignore errors in encode and allow hashmaps with enum keys closes #21470 on main rust repository was fixed on rust-lang/rustc-serialize (see https://github.com/rust-lang/rustc-serialize/pull/32) --- src/libserialize/json.rs | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 5f4ba8ef9fc..d86bf8e4871 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -97,7 +97,7 @@ //! }; //! //! // Serialize using `json::encode` -//! let encoded = json::encode(&object); +//! let encoded = json::encode(&object).unwrap(); //! //! // Deserialize using `json::decode` //! let decoded: TestStruct = json::decode(encoded.as_slice()).unwrap(); @@ -143,7 +143,7 @@ //! uid: 1, //! dsc: "test".to_string(), //! val: num.to_json(), -//! }); +//! }).unwrap(); //! println!("data: {}", data); //! // data: {"uid":1,"dsc":"test","val":"0.0001+12.539j"}; //! } @@ -316,13 +316,13 @@ pub fn decode(s: &str) -> DecodeResult { } /// Shortcut function to encode a `T` into a JSON `String` -pub fn encode(object: &T) -> string::String { +pub fn encode(object: &T) -> Result { let mut s = String::new(); { let mut encoder = Encoder::new(&mut s); - let _ = object.encode(&mut encoder); + try!(object.encode(&mut encoder)); } - s + Ok(s) } impl fmt::Display for ErrorCode { @@ -536,7 +536,6 @@ impl<'a> ::Encoder for Encoder<'a> { fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult where F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } f(self) } @@ -550,10 +549,10 @@ impl<'a> ::Encoder for Encoder<'a> { // enums are encoded as strings or objects // Bunny => "Bunny" // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]} - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } if cnt == 0 { escape_str(self.writer, name) } else { + if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } try!(write!(self.writer, "{{\"variant\":")); try!(escape_str(self.writer, name)); try!(write!(self.writer, ",\"fields\":[")); @@ -785,7 +784,6 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult where F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } f(self) } @@ -797,10 +795,10 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { -> EncodeResult where F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } if cnt == 0 { escape_str(self.writer, name) } else { + if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } try!(write!(self.writer, "{{\n")); self.curr_indent += self.indent; try!(spaces(self.writer, self.curr_indent)); @@ -3537,6 +3535,24 @@ mod tests { } } + #[test] + fn test_hashmap_with_enum_key() { + use std::collections::HashMap; + use json; + #[derive(RustcEncodable, Eq, Hash, PartialEq, RustcDecodable, Show)] + enum Enum { + Foo, + #[allow(dead_code)] + Bar, + } + let mut map = HashMap::new(); + map.insert(Enum::Foo, 0); + let result = json::encode(&map).unwrap(); + assert_eq!(&result[], r#"{"Foo":0}"#); + let decoded: HashMap = json::decode(result.as_slice()).unwrap(); + assert_eq!(map, decoded); + } + #[test] fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { use std::collections::HashMap; From 82b0b0fcc70593ff13176795f1bc82c86c7c618f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 26 Jan 2015 16:10:22 +0100 Subject: [PATCH 2/2] fallout --- src/libsyntax/parse/mod.rs | 2 +- src/test/run-pass/deriving-encodable-decodable-box.rs | 2 +- src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs | 2 +- src/test/run-pass/issue-14021.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 8cb7ee5b337..6dfd1fddcf7 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -854,7 +854,7 @@ mod test { #[test] fn string_to_tts_1 () { let tts = string_to_tts("fn a (b : i32) { b; }".to_string()); - assert_eq!(json::encode(&tts), + assert_eq!(json::encode(&tts).unwrap(), "[\ {\ \"variant\":\"TtToken\",\ diff --git a/src/test/run-pass/deriving-encodable-decodable-box.rs b/src/test/run-pass/deriving-encodable-decodable-box.rs index 1a204fa3e20..a0888850aaf 100644 --- a/src/test/run-pass/deriving-encodable-decodable-box.rs +++ b/src/test/run-pass/deriving-encodable-decodable-box.rs @@ -24,7 +24,7 @@ struct A { fn main() { let obj = A { foo: box [true, false] }; - let s = json::encode(&obj); + let s = json::encode(&obj).unwrap(); let obj2: A = json::decode(s.as_slice()).unwrap(); assert!(obj.foo == obj2.foo); } diff --git a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs index 3b2c1d9f27c..a5453d26170 100644 --- a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs +++ b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs @@ -35,7 +35,7 @@ fn main() { foo: Cell::new(true), bar: RefCell::new( A { baz: 2 } ) }; - let s = json::encode(&obj); + let s = json::encode(&obj).unwrap(); let obj2: B = json::decode(s.as_slice()).unwrap(); assert!(obj.foo.get() == obj2.foo.get()); assert!(obj.bar.borrow().baz == obj2.bar.borrow().baz); diff --git a/src/test/run-pass/issue-14021.rs b/src/test/run-pass/issue-14021.rs index 509459a2ab3..8c4dd7ddc9a 100644 --- a/src/test/run-pass/issue-14021.rs +++ b/src/test/run-pass/issue-14021.rs @@ -20,7 +20,7 @@ struct UnitLikeStruct; pub fn main() { let obj = UnitLikeStruct; - let json_str: String = json::encode(&obj); + let json_str: String = json::encode(&obj).unwrap(); let json_object = json::from_str(json_str.as_slice()); let mut decoder = json::Decoder::new(json_object.unwrap());