Skip to content

Commit

Permalink
add TimeStamp type to facilitate deserialization (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
saghm authored and kyeah committed Feb 18, 2018
1 parent 4b4cc67 commit 39be458
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
21 changes: 21 additions & 0 deletions src/bson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,27 @@ impl Bson {
}
}

/// `TimeStamp` representation in struct for serde serialization
///
/// Just a helper for convenience
///
/// ```rust,ignore
/// #[macro_use]
/// extern crate serde_derive;
/// extern crate bson;
/// use bson::TimeStamp;
///
/// #[derive(Serialize, Deserialize)]
/// struct Foo {
/// timestamp: TimeStamp,
/// }
/// ```
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct TimeStamp {
pub t: u32,
pub i: u32,
}

/// `DateTime` representation in struct for serde serialization
///
/// Just a helper for convenience
Expand Down
23 changes: 22 additions & 1 deletion src/decoder/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde::de::{self, Deserialize, Deserializer, Visitor, MapAccess, SeqAccess,
DeserializeSeed, EnumAccess};
use serde::de::{Error, Unexpected};

use bson::{Bson, UtcDateTime};
use bson::{Bson, TimeStamp, UtcDateTime};
use oid::ObjectId;
use ordered::{OrderedDocument, OrderedDocumentIntoIterator, OrderedDocumentVisitor};
use super::error::{DecoderError, DecoderResult};
Expand Down Expand Up @@ -601,6 +601,26 @@ impl<'de> Deserializer<'de> for MapDecoder {
}
}

impl<'de> Deserialize<'de> for TimeStamp {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
use serde::de::Error;

match Bson::deserialize(deserializer)? {
Bson::TimeStamp(ts) => {
let ts = ts.to_be();

Ok(TimeStamp {
t: ((ts as u64) >> 32) as u32,
i: (ts & 0xFFFF_FFFF) as u32,
})
}
_ => Err(D::Error::custom("expecting UtcDateTime")),
}
}
}

impl<'de> Deserialize<'de> for UtcDateTime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
Expand All @@ -613,3 +633,4 @@ impl<'de> Deserialize<'de> for UtcDateTime {
}
}
}

2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extern crate linked_hash_map;
extern crate hostname;
extern crate hex;

pub use self::bson::{Bson, Document, Array, UtcDateTime};
pub use self::bson::{Bson, Document, Array, TimeStamp, UtcDateTime};
pub use self::encoder::{encode_document, to_bson, Encoder, EncoderResult, EncoderError};
pub use self::decoder::{decode_document, decode_document_utf8_lossy, from_bson, Decoder, DecoderResult, DecoderError};
pub use self::ordered::{ValueAccessError, ValueAccessResult};
Expand Down
16 changes: 16 additions & 0 deletions tests/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ fn test_de_map() {
assert_eq!(expected, map);
}

#[test]
fn test_de_timestamp() {
use bson::TimeStamp;

#[derive(Deserialize, Eq, PartialEq, Debug)]
struct Foo {
ts: TimeStamp,
}

let foo: Foo = bson::from_bson(Bson::Document(doc! {
"ts": Bson::TimeStamp(0x0A00_0000_0C00_0000),
})).unwrap();

assert_eq!(foo.ts, TimeStamp { t: 12, i: 10 });
}

#[test]
fn test_ser_datetime() {
use chrono::{Utc, Timelike};
Expand Down

0 comments on commit 39be458

Please sign in to comment.