Skip to content

Commit a402be3

Browse files
committed
Support encoding and decoding of object ids
Make ObjectId usable within struct that implement encodable and decodable. Serializes to and from hex string.
1 parent d4f20e2 commit a402be3

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/oid.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use crypto::md5::Md5;
55

66
use byteorder::{ByteOrder, BigEndian, LittleEndian};
77
use rand::{Rng, OsRng};
8-
use rustc_serialize::hex::{self, FromHex};
8+
use rustc_serialize::hex::{self, FromHex, ToHex};
9+
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
910
use time;
1011

1112
use std::{fmt, io, error, result};
@@ -145,6 +146,11 @@ impl ObjectId {
145146
self.id
146147
}
147148

149+
/// Returns a 12-byte (24-char) hexadecimal string
150+
pub fn to_string(&self) -> String {
151+
self.id.to_hex()
152+
}
153+
148154
/// Retrieves the timestamp (seconds since epoch) from an ObjectId.
149155
pub fn timestamp(&self) -> u32 {
150156
BigEndian::read_u32(&self.id)
@@ -265,6 +271,19 @@ impl ObjectId {
265271
}
266272
}
267273

274+
impl Decodable for ObjectId {
275+
fn decode<D: Decoder>(d: &mut D) -> result::Result<Self, D::Error> {
276+
let str = try!(d.read_str());
277+
Ok(ObjectId::with_string(&str).unwrap())
278+
}
279+
}
280+
281+
impl Encodable for ObjectId {
282+
fn encode<S: Encoder>(&self, s: &mut S) -> result::Result<(), S::Error> {
283+
s.emit_str(&self.to_string())
284+
}
285+
}
286+
268287
#[test]
269288
fn pid_generation() {
270289
let pid = unsafe { libc::getpid() as u16 };

tests/modules/oid.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use bson::oid::ObjectId;
22
use rustc_serialize::hex::ToHex;
3+
use rustc_serialize::json;
34

45
#[test]
56
fn deserialize() {
@@ -63,6 +64,7 @@ fn byte_string_oid() {
6364
0x83u8, 0x2Bu8, 0x21u8, 0x8Eu8];
6465

6566
assert_eq!(bytes, oid.bytes());
67+
assert_eq!(s, oid.to_string());
6668
}
6769

6870
#[test]
@@ -96,3 +98,21 @@ fn increasing() {
9698
let oid2 = oid2_res.unwrap();
9799
assert!(oid1 < oid2);
98100
}
101+
102+
#[derive(RustcEncodable,RustcDecodable,PartialEq,Debug)]
103+
struct StructWithObjectId {
104+
id: ObjectId
105+
}
106+
107+
#[test]
108+
fn use_in_rustc_serialize() {
109+
let s = "541b1a00e8a23afa832b218e";
110+
let s = StructWithObjectId {
111+
id: ObjectId::with_string(s).unwrap()
112+
};
113+
let encoded = json::encode(&s).unwrap();
114+
assert_eq!("{\"id\":\"541b1a00e8a23afa832b218e\"}", encoded);
115+
116+
let decoded: StructWithObjectId = json::decode(&encoded).unwrap();
117+
assert_eq!(s, decoded);
118+
}

0 commit comments

Comments
 (0)