Skip to content

Commit d33712e

Browse files
committed
Fix Option handling
With this change, the library becomes somewhat useful. Closes #1.
1 parent 4aaa43d commit d33712e

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

Diff for: src/maxminddb/decoder.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ extern crate serialize;
44
use std::str;
55

66
use super::{Array, Boolean, Byte, DataRecord, DecodingError, Double, Error,
7-
Float, Int32, Map, String, Uint16, Uint32, Uint64};
7+
Float, Int32, Map, Null, String, Uint16, Uint32, Uint64};
88

99
macro_rules! expect(
10+
($e:expr, Null) => ({
11+
match $e {
12+
Null => Ok(()),
13+
other => Err(DecodingError(format!("Error decoding Null as {}", other)))
14+
}
15+
});
1016
($e:expr, $t:ident) => ({
1117
match $e {
1218
$t(v) => Ok(v),
@@ -40,7 +46,7 @@ pub type DecodeResult<T> = Result<T, Error>;
4046
impl serialize::Decoder<Error> for Decoder {
4147
fn read_nil(&mut self) -> DecodeResult<()> {
4248
debug!("read_nil");
43-
Err(DecodingError("nil data not supported by MaxMind DB format".to_string()))
49+
expect!(self.pop(), Null)
4450
}
4551

4652
fn read_u64(&mut self) -> DecodeResult<u64 > {
@@ -213,7 +219,13 @@ impl serialize::Decoder<Error> for Decoder {
213219
let mut obj = try!(expect!(self.pop(), Map));
214220

215221
let value = match obj.pop(&name.to_string()) {
216-
None => return Err(DecodingError(format!("Unknown struct field {}", name.to_string()))),
222+
None => {
223+
self.stack.push(Null);
224+
match f(self) {
225+
Ok(v) => v,
226+
Err(_) => return Err(DecodingError(format!("Unknown struct field {}", name.to_string()))),
227+
}
228+
},
217229
Some(record) => {
218230
self.stack.push(record);
219231
try!(f(self))
@@ -252,9 +264,11 @@ impl serialize::Decoder<Error> for Decoder {
252264
}
253265

254266
fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> DecodeResult<T>) -> DecodeResult<T> {
255-
let value = self.pop();
256-
self.stack.push(value);
257-
f(self, true)
267+
debug!("read_option()");
268+
match self.pop() {
269+
Null => f(self, false),
270+
value => { self.stack.push(value); f(self, true) }
271+
}
258272
}
259273

260274
fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> {

Diff for: src/maxminddb/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pub enum DataRecord {
5454
Boolean(bool),
5555
Array(Array),
5656
Float(f32),
57+
Null,
5758
}
5859

5960
pub type Array = Vec<DataRecord>;
@@ -73,6 +74,7 @@ impl fmt::Show for DataRecord {
7374
&Boolean(v) => v.fmt(f),
7475
&Array(ref v) => v.fmt(f),
7576
&Float(v) => v.fmt(f),
77+
&Null => "Null".fmt(f),
7678
}
7779
}
7880
}

0 commit comments

Comments
 (0)