Skip to content

Commit 4f4a3df

Browse files
committed
Decoding json now defaults Option<_> to None.
Closes #12794
1 parent 6f34760 commit 4f4a3df

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

src/libserialize/json.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -2128,7 +2128,15 @@ impl ::Decoder<DecoderError> for Decoder {
21282128
let mut obj = try!(expect!(self.pop(), Object));
21292129

21302130
let value = match obj.pop(&name.to_string()) {
2131-
None => return Err(MissingFieldError(name.to_string())),
2131+
None => {
2132+
// Add a Null and try to parse it as an Option<_>
2133+
// to get None as a default value.
2134+
self.stack.push(Null);
2135+
match f(self) {
2136+
Ok(x) => x,
2137+
Err(_) => return Err(MissingFieldError(name.to_string())),
2138+
}
2139+
},
21322140
Some(json) => {
21332141
self.stack.push(json);
21342142
try!(f(self))
@@ -2167,6 +2175,7 @@ impl ::Decoder<DecoderError> for Decoder {
21672175
}
21682176

21692177
fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> DecodeResult<T>) -> DecodeResult<T> {
2178+
debug!("read_option()");
21702179
match self.pop() {
21712180
Null => f(self, false),
21722181
value => { self.stack.push(value); f(self, true) }
@@ -2372,6 +2381,33 @@ mod tests {
23722381
use std::{i64, u64, f32, f64, io};
23732382
use std::collections::TreeMap;
23742383

2384+
#[deriving(Decodable, Eq, PartialEq, Show)]
2385+
struct OptionData {
2386+
opt: Option<uint>,
2387+
}
2388+
2389+
#[test]
2390+
fn test_decode_option_none() {
2391+
let s ="{}";
2392+
let obj: OptionData = super::decode(s).unwrap();
2393+
assert_eq!(obj, OptionData { opt: None });
2394+
}
2395+
2396+
#[test]
2397+
fn test_decode_option_some() {
2398+
let s = "{ \"opt\": 10 }";
2399+
let obj: OptionData = super::decode(s).unwrap();
2400+
assert_eq!(obj, OptionData { opt: Some(10u) });
2401+
}
2402+
2403+
#[test]
2404+
fn test_decode_option_malformed() {
2405+
check_err::<OptionData>("{ \"opt\": [] }",
2406+
ExpectedError("Number".to_string(), "[]".to_string()));
2407+
check_err::<OptionData>("{ \"opt\": false }",
2408+
ExpectedError("Number".to_string(), "false".to_string()));
2409+
}
2410+
23752411
#[deriving(PartialEq, Encodable, Decodable, Show)]
23762412
enum Animal {
23772413
Dog,

0 commit comments

Comments
 (0)