Skip to content
This repository has been archived by the owner on Aug 15, 2021. It is now read-only.

Commit

Permalink
Option<T> does now round-trip.
Browse files Browse the repository at this point in the history
closes #5
  • Loading branch information
pyfisch committed Mar 30, 2016
1 parent beb76e7 commit f8bdc0e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "serde_cbor"
version = "0.3.1"
version = "0.3.2"
authors = ["Pyfisch <[email protected]>"]
repository = "https://github.com/pyfisch/cbor"
documentation = "http://pyfisch.github.io/cbor/serde_cbor/index.html"
Expand Down
25 changes: 22 additions & 3 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ const MAX_SEQ_LEN: u64 = 524288;
/// A structure that deserializes CBOR into Rust values.
pub struct Deserializer<R: Read> {
reader: R,
first: Option<u8>,
}

impl<R: Read> Deserializer<R> {
/// Creates the CBOR parser from an `std::io::Read`.
#[inline]
pub fn new(reader: R) -> Deserializer<R> {
Deserializer { reader: reader }
Deserializer { reader: reader, first: None }
}

/// The `Deserializer::end` method should be called after a value has been fully deserialized.
Expand All @@ -35,7 +36,8 @@ impl<R: Read> Deserializer<R> {

#[inline]
fn parse_value<V: Visitor>(&mut self, visitor: V) -> Result<V::Value> {
let first = try!(self.read_u8());
let first = self.first.unwrap();
self.first = None;
match (first & 0b111_00000) >> 5 {
0 => self.parse_uint(first, visitor),
1 => self.parse_int(first, visitor),
Expand Down Expand Up @@ -155,6 +157,7 @@ impl<R: Read> Deserializer<R> {
#[inline]
fn parse_tag<V: Visitor>(&mut self, first: u8, visitor: V) -> Result<V::Value> {
try!(self.parse_additional_information(first));
self.first = Some(try!(self.read_u8()));
self.parse_value(visitor)
}

Expand Down Expand Up @@ -198,7 +201,23 @@ impl<R: Read> de::Deserializer for Deserializer<R> {

#[inline]
fn deserialize<V: Visitor>(&mut self, visitor: V) -> Result<V::Value> {
self.parse_value(visitor)
if self.first.is_none() {
self.first = Some(try!(self.read_u8()));
}
let result = self.parse_value(visitor);
self.first = None;
result
}

#[inline]
fn deserialize_option<V: Visitor>(&mut self, mut visitor: V) -> Result<V::Value> {
self.first = Some(try!(self.read_u8()));
if self.first == Some(0b111_10110) {
self.first = None;
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions tests/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,28 @@ fn test_kietaub_file() {
let value_result: error::Result<Value> = de::from_slice(file);
assert!(value_result.is_ok());
}

#[test]
fn test_option_roundtrip() {
let obj1 = Some(10u32);

let mut v = vec![];
assert!(serde_cbor::ser::to_writer(&mut v, &obj1).is_ok());
println!("{:?}", v);
let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);
println!("{:?}", obj2);

assert_eq!(obj1, obj2.unwrap());
}

#[test]
fn test_option_none_roundtrip() {
let obj1 = None;

let mut v = vec![];
assert!(serde_cbor::ser::to_writer(&mut v, &obj1).is_ok());
println!("{:?}", v);
let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);

assert_eq!(obj1, obj2.unwrap());
}

0 comments on commit f8bdc0e

Please sign in to comment.