summary refs log tree commit diff
path: root/src/libserialize
diff options
context:
space:
mode:
authorJonas Hietala <tradet.h@gmail.com>2014-09-09 07:28:59 +0200
committerJonas Hietala <tradet.h@gmail.com>2014-09-09 07:28:59 +0200
commit4f4a3dfb1a2a46021bc47f19bca48b0c4df94dd5 (patch)
tree8e61a0d14af68f1aef55b6e3a0ea89120a840683 /src/libserialize
parent6f34760e4173dda94162502153fe4c5a2a96fc9d (diff)
downloadrust-4f4a3dfb1a2a46021bc47f19bca48b0c4df94dd5.tar.gz
rust-4f4a3dfb1a2a46021bc47f19bca48b0c4df94dd5.zip
Decoding json now defaults Option<_> to None.
Closes #12794
Diffstat (limited to 'src/libserialize')
-rw-r--r--src/libserialize/json.rs38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index b29200597aa..733bc593922 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -2128,7 +2128,15 @@ impl ::Decoder<DecoderError> for Decoder {
         let mut obj = try!(expect!(self.pop(), Object));
 
         let value = match obj.pop(&name.to_string()) {
-            None => return Err(MissingFieldError(name.to_string())),
+            None => {
+                // Add a Null and try to parse it as an Option<_>
+                // to get None as a default value.
+                self.stack.push(Null);
+                match f(self) {
+                    Ok(x) => x,
+                    Err(_) => return Err(MissingFieldError(name.to_string())),
+                }
+            },
             Some(json) => {
                 self.stack.push(json);
                 try!(f(self))
@@ -2167,6 +2175,7 @@ impl ::Decoder<DecoderError> for Decoder {
     }
 
     fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> DecodeResult<T>) -> DecodeResult<T> {
+        debug!("read_option()");
         match self.pop() {
             Null => f(self, false),
             value => { self.stack.push(value); f(self, true) }
@@ -2372,6 +2381,33 @@ mod tests {
     use std::{i64, u64, f32, f64, io};
     use std::collections::TreeMap;
 
+    #[deriving(Decodable, Eq, PartialEq, Show)]
+    struct OptionData {
+        opt: Option<uint>,
+    }
+
+    #[test]
+    fn test_decode_option_none() {
+        let s ="{}";
+        let obj: OptionData = super::decode(s).unwrap();
+        assert_eq!(obj, OptionData { opt: None });
+    }
+
+    #[test]
+    fn test_decode_option_some() {
+        let s = "{ \"opt\": 10 }";
+        let obj: OptionData = super::decode(s).unwrap();
+        assert_eq!(obj, OptionData { opt: Some(10u) });
+    }
+
+    #[test]
+    fn test_decode_option_malformed() {
+        check_err::<OptionData>("{ \"opt\": [] }",
+                                ExpectedError("Number".to_string(), "[]".to_string()));
+        check_err::<OptionData>("{ \"opt\": false }",
+                                ExpectedError("Number".to_string(), "false".to_string()));
+    }
+
     #[deriving(PartialEq, Encodable, Decodable, Show)]
     enum Animal {
         Dog,