Skip to content

Commit ab59c34

Browse files
committed
Encoder and Decoder errors for serde de/serialization
1 parent 523a113 commit ab59c34

File tree

7 files changed

+159
-143
lines changed

7 files changed

+159
-143
lines changed

serde-tests/test.rs.in

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ macro_rules! t {
6060
macro_rules! encode( ($t:expr) => ({
6161
let mut e = Encoder::new();
6262
t!($t.serialize(&mut e));
63-
e.unwrap()
63+
match e.bson() {
64+
Ok(b) => b,
65+
Err(e) => panic!("Failed to serialize: {}", e),
66+
}
6467
}) );
6568

6669
macro_rules! decode( ($t:expr) => ({

src/bson.rs

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -365,49 +365,45 @@ impl Bson {
365365
}
366366
}
367367
}
368-
// TODO: Actual error
369-
_ => unreachable!()
368+
_ => panic!("Attempted conversion of invalid data type: {}", self),
370369
}
371370
}
372371

373372
pub fn from_extended_document(values: Document) -> Bson {
374-
if values.contains_key("$regex") {
375-
if let Some(&Bson::String(ref pat)) = values.get("$regex") {
376-
if let Some(&Bson::String(ref opt)) = values.get("$options") {
377-
return Bson::RegExp(pat.to_owned(), opt.to_owned());
378-
}
379-
}
373+
if values.len() == 2 {
374+
if let (Ok(pat), Ok(opt)) = (values.get_str("$regex"),
375+
values.get_str("$options")) {
376+
return Bson::RegExp(pat.to_owned(), opt.to_owned());
380377

381-
} else if let Some(&Bson::String(ref code)) = values.get("$code") {
382-
if let Some(&Bson::Document(ref scope)) = values.get("$scope") {
378+
} else if let (Ok(code), Ok(scope)) = (values.get_str("$code"),
379+
values.get_document("$scope")) {
383380
return Bson::JavaScriptCodeWithScope(code.to_owned(), scope.to_owned());
384-
} else {
385-
return Bson::JavaScriptCode(code.to_owned());
386-
}
387381

388-
} else if let Some(&Bson::I32(t)) = values.get("t") {
389-
if let Some(&Bson::I32(i)) = values.get("i") {
382+
} else if let (Ok(t), Ok(i)) = (values.get_i32("t"),
383+
values.get_i32("i")) {
390384
let timestamp = ((t as i64) << 32) + (i as i64);
391-
return Bson::TimeStamp(timestamp)
392-
}
385+
return Bson::TimeStamp(timestamp);
393386

394-
} else if let Some(&Bson::I64(t)) = values.get("t") {
395-
if let Some(&Bson::I64(i)) = values.get("i") {
387+
} else if let (Ok(t), Ok(i)) = (values.get_i64("t"),
388+
values.get_i64("i")) {
396389
let timestamp = (t << 32) + i;
397-
return Bson::TimeStamp(timestamp)
398-
}
390+
return Bson::TimeStamp(timestamp);
399391

400-
} else if let Some(&Bson::String(ref hex)) = values.get("$binary") {
401-
if let Some(&Bson::I64(t)) = values.get("type") {
392+
} else if let (Ok(hex), Ok(t)) = (values.get_str("$binary"),
393+
values.get_i64("type")) {
402394
let ttype = t as u8;
403395
return Bson::Binary(From::from(ttype), hex.from_hex().unwrap());
404396
}
405397

406-
} else if let Some(&Bson::String(ref hex)) = values.get("$oid") {
407-
return Bson::ObjectId(oid::ObjectId::with_string(hex).unwrap());
398+
} else if values.len() == 1 {
399+
if let Ok(code) = values.get_str("$code") {
400+
return Bson::JavaScriptCode(code.to_owned());
401+
402+
} else if let Ok(hex) = values.get_str("$oid") {
403+
return Bson::ObjectId(oid::ObjectId::with_string(hex).unwrap());
408404

409-
} else if let Some(&Bson::Document(ref doc)) = values.get("$date") {
410-
if let Some(&Bson::I64(long)) = doc.get("$numberLong") {
405+
} else if let Ok(long) = values.get_document("$date")
406+
.and_then(|inner| inner.get_i64("$numberLong")) {
411407
return Bson::UtcDatetime(UTC.timestamp(long / 1000, (long % 1000) as u32 * 1000000));
412408
}
413409
}

src/decoder/serde.rs

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,43 @@ use super::error::{DecoderError, DecoderResult};
1010

1111
pub struct BsonVisitor;
1212

13+
14+
impl Deserialize for ObjectId {
15+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
16+
where D: Deserializer,
17+
{
18+
deserializer.visit_map(BsonVisitor)
19+
.and_then(|bson| if let Bson::ObjectId(oid) = bson {
20+
Ok(oid)
21+
} else {
22+
Err(de::Error::syntax(&format!("expected objectId extended document, found {}", bson)))
23+
})
24+
}
25+
}
26+
27+
impl Deserialize for OrderedDocument {
28+
/// Deserialize this value given this `Deserializer`.
29+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
30+
where D: Deserializer,
31+
{
32+
deserializer.visit_map(BsonVisitor)
33+
.and_then(|bson| if let Bson::Document(doc) = bson {
34+
Ok(doc)
35+
} else {
36+
Err(de::Error::syntax(&format!("expected document, found extended JSON data type: {}", bson)))
37+
})
38+
}
39+
}
40+
41+
impl Deserialize for Bson {
42+
#[inline]
43+
fn deserialize<D>(deserializer: &mut D) -> Result<Bson, D::Error>
44+
where D: Deserializer,
45+
{
46+
deserializer.visit(BsonVisitor)
47+
}
48+
}
49+
1350
impl Visitor for BsonVisitor {
1451
type Value = Bson;
1552

@@ -96,49 +133,11 @@ impl Visitor for BsonVisitor {
96133
}
97134
}
98135

99-
impl Deserialize for ObjectId {
100-
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
101-
where D: Deserializer,
102-
{
103-
deserializer.visit_map(BsonVisitor)
104-
.and_then(|bson| if let Bson::ObjectId(oid) = bson {
105-
Ok(oid)
106-
} else {
107-
unimplemented!()
108-
})
109-
}
110-
}
111-
112-
impl Deserialize for OrderedDocument {
113-
/// Deserialize this value given this `Deserializer`.
114-
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
115-
where D: Deserializer,
116-
{
117-
deserializer.visit_map(BsonVisitor)
118-
.and_then(|bson| if let Bson::Document(doc) = bson {
119-
Ok(doc)
120-
} else {
121-
unimplemented!()
122-
})
123-
}
124-
}
125-
126-
impl Deserialize for Bson {
127-
#[inline]
128-
fn deserialize<D>(deserializer: &mut D) -> Result<Bson, D::Error>
129-
where D: Deserializer,
130-
{
131-
deserializer.visit(BsonVisitor)
132-
}
133-
}
134-
135-
/// Creates a `serde::Deserializer` from a `json::Value` object.
136136
pub struct Decoder {
137137
value: Option<Bson>,
138138
}
139139

140140
impl Decoder {
141-
/// Creates a new deserializer instance for deserializing the specified JSON value.
142141
pub fn new(value: Bson) -> Decoder {
143142
Decoder {
144143
value: Some(value),
@@ -264,25 +263,29 @@ impl<'a> VariantVisitor for VariantDecoder<'a> {
264263
fn visit_variant<V>(&mut self) -> DecoderResult<V>
265264
where V: Deserialize,
266265
{
267-
Deserialize::deserialize(&mut Decoder::new(self.variant.take().unwrap()))
266+
Deserialize::deserialize(&mut Decoder::new(try!(self.variant.take()
267+
.ok_or(DecoderError::EndOfStream))))
268268
}
269269

270270
fn visit_unit(&mut self) -> DecoderResult<()> {
271-
Deserialize::deserialize(&mut Decoder::new(self.val.take().unwrap()))
271+
Deserialize::deserialize(&mut Decoder::new(try!(self.val.take()
272+
.ok_or(DecoderError::EndOfStream))))
272273
}
273274

274275
fn visit_newtype<T>(&mut self) -> DecoderResult<T>
275276
where T: Deserialize,
276277
{
277-
Deserialize::deserialize(&mut Decoder::new(self.val.take().unwrap()))
278+
Deserialize::deserialize(&mut Decoder::new(try!(self.val.take()
279+
.ok_or(DecoderError::EndOfStream))))
278280
}
279281

280282
fn visit_tuple<V>(&mut self,
281283
_len: usize,
282284
visitor: V) -> DecoderResult<V::Value>
283285
where V: Visitor,
284286
{
285-
if let Bson::Array(fields) = self.val.take().unwrap() {
287+
if let Bson::Array(fields) = try!(self.val.take()
288+
.ok_or(DecoderError::EndOfStream)) {
286289
Deserializer::visit(
287290
&mut SeqDecoder {
288291
de: self.de,
@@ -301,7 +304,8 @@ impl<'a> VariantVisitor for VariantDecoder<'a> {
301304
visitor: V) -> DecoderResult<V::Value>
302305
where V: Visitor,
303306
{
304-
if let Bson::Document(fields) = self.val.take().unwrap() {
307+
if let Bson::Document(fields) = try!(self.val.take()
308+
.ok_or(DecoderError::EndOfStream)) {
305309
Deserializer::visit(
306310
&mut MapDecoder {
307311
de: self.de,
@@ -398,7 +402,9 @@ impl<'a> MapVisitor for MapDecoder<'a> {
398402
fn visit_value<T>(&mut self) -> DecoderResult<T>
399403
where T: Deserialize
400404
{
401-
let value = self.value.take().unwrap();
405+
let value = try!(self.value.take()
406+
.ok_or(DecoderError::EndOfStream));
407+
402408
self.de.value = Some(value);
403409
Ok(try!(Deserialize::deserialize(self.de)))
404410
}

src/encoder/error.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use std::{io, error, fmt};
22
use byteorder;
3+
use super::serde::State;
34

45
/// Possible errors that can arise during encoding.
56
#[derive(Debug)]
67
pub enum EncoderError {
78
IoError(io::Error),
9+
InvalidMapKeyType(State),
10+
InvalidState(State),
11+
EmptyState,
812
}
913

1014
impl From<io::Error> for EncoderError {
@@ -22,7 +26,10 @@ impl From<byteorder::Error> for EncoderError {
2226
impl fmt::Display for EncoderError {
2327
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
2428
match self {
25-
&EncoderError::IoError(ref inner) => inner.fmt(fmt)
29+
&EncoderError::IoError(ref inner) => inner.fmt(fmt),
30+
&EncoderError::InvalidMapKeyType(ref inner) => write!(fmt, "Invalid map key type: {:?}", inner),
31+
&EncoderError::InvalidState(ref inner) => write!(fmt, "Invalid state emitted: {:?}", inner),
32+
&EncoderError::EmptyState => write!(fmt, "No state emitted"),
2633
}
2734
}
2835
}
@@ -31,11 +38,15 @@ impl error::Error for EncoderError {
3138
fn description(&self) -> &str {
3239
match self {
3340
&EncoderError::IoError(ref inner) => inner.description(),
41+
&EncoderError::InvalidMapKeyType(_) => "Invalid map key type",
42+
&EncoderError::InvalidState(_) => "Invalid state emitted",
43+
&EncoderError::EmptyState => "No state emitted",
3444
}
3545
}
3646
fn cause(&self) -> Option<&error::Error> {
3747
match self {
38-
&EncoderError::IoError(ref inner) => Some(inner)
48+
&EncoderError::IoError(ref inner) => Some(inner),
49+
_ => None,
3950
}
4051
}
4152
}

src/encoder/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ fn encode_bson<W: Write + ?Sized>(writer: &mut W, key: &str, val: &Bson) -> Enco
136136
}
137137

138138
/// Encode a `T` Serializable into a BSON `Value`.
139-
pub fn to_bson<T>(value: &T) -> Bson
139+
pub fn to_bson<T>(value: &T) -> EncoderResult<Bson>
140140
where T: Serialize
141141
{
142142
let mut ser = Encoder::new();
143-
value.serialize(&mut ser).unwrap();
144-
ser.unwrap()
143+
try!(value.serialize(&mut ser));
144+
ser.bson()
145145
}

0 commit comments

Comments
 (0)