Skip to content

Commit 4158d18

Browse files
committed
implement Display for Bson and OrderedDocument
1 parent 1f66ffd commit 4158d18

File tree

3 files changed

+121
-1
lines changed

3 files changed

+121
-1
lines changed

src/bson.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
//! BSON definition
2323
24+
use std::fmt::{Display, Error, Formatter};
25+
use std::str;
26+
2427
use chrono::{DateTime, UTC};
2528
use rustc_serialize::json;
2629
use rustc_serialize::hex::ToHex;
@@ -54,6 +57,60 @@ pub type Array = Vec<Bson>;
5457
/// Alias for `OrderedDocument`.
5558
pub type Document = OrderedDocument;
5659

60+
impl Display for Bson {
61+
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
62+
let bson_string = match self {
63+
&Bson::FloatingPoint(f) => format!("{}", f),
64+
&Bson::String(ref s) => format!("\"{}\"", s),
65+
&Bson::Array(ref vec) => {
66+
let mut string = "[".to_owned();
67+
68+
for bson in vec.iter() {
69+
if !string.eq("[") {
70+
string.push_str(", ");
71+
}
72+
73+
string.push_str(&format!("{}", bson));
74+
}
75+
76+
string.push_str("]");
77+
string
78+
},
79+
&Bson::Document(ref doc) => format!("{}", doc),
80+
&Bson::Boolean(b) => format!("{}", b),
81+
&Bson::Null => "null".to_owned(),
82+
&Bson::RegExp(ref pat, ref opt) => format!("/{}/{}", pat, opt),
83+
&Bson::JavaScriptCode(ref s) |
84+
&Bson::JavaScriptCodeWithScope(ref s, _) => s.to_owned(),
85+
&Bson::I32(i) => format!("{}", i),
86+
&Bson::I64(i) => format!("{}", i),
87+
&Bson::TimeStamp(i) => {
88+
let time = (i >> 32) as i32;
89+
let inc = (i & 0xFFFFFFFF) as i32;
90+
91+
format!("Timestamp({}, {})", time, inc)
92+
},
93+
&Bson::Binary(t, ref vec) => {
94+
let string = unsafe { str::from_utf8_unchecked(vec) };
95+
format!("BinData({}, \"{}\")", u8::from(t), string)
96+
}
97+
&Bson::ObjectId(ref id) => {
98+
let mut vec = vec![];
99+
100+
for byte in id.bytes().iter() {
101+
vec.push(byte.to_owned());
102+
}
103+
104+
let string = unsafe { String::from_utf8_unchecked(vec) };
105+
format!("ObjectId(\"{}\")", string)
106+
}
107+
&Bson::UtcDatetime(date_time) => format!("Date(\"{}\")", date_time)
108+
};
109+
110+
fmt.write_str(&bson_string)
111+
}
112+
}
113+
57114
impl From<f32> for Bson {
58115
fn from(a: f32) -> Bson {
59116
Bson::FloatingPoint(a as f64)

src/ordered.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use bson::Bson;
22
use std::collections::BTreeMap;
3+
use std::fmt::{Display, Error, Formatter};
34
use std::iter::{FromIterator, Map};
45
use std::vec::IntoIter;
56
use std::slice;
@@ -11,6 +12,23 @@ pub struct OrderedDocument {
1112
document: BTreeMap<String, Bson>,
1213
}
1314

15+
impl Display for OrderedDocument {
16+
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
17+
let mut string = "{ ".to_owned();
18+
19+
for (key, value) in self.iter() {
20+
if !string.eq("{ ") {
21+
string.push_str(", ");
22+
}
23+
24+
string.push_str(&format!("{}: {}", key, value));
25+
}
26+
27+
string.push_str(" }");
28+
fmt.write_str(&string)
29+
}
30+
}
31+
1432
/// An iterator over OrderedDocument entries.
1533
pub struct OrderedDocumentIntoIterator {
1634
vec_iter: IntoIter<String>,

tests/lib.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
1-
#[macro_use(bson, doc)]
1+
#[macro_use]
22
extern crate bson;
3+
extern crate chrono;
34
extern crate rustc_serialize;
45

56
mod modules;
7+
8+
use bson::Bson;
9+
use bson::spec::BinarySubtype;
10+
use bson::oid::ObjectId;
11+
use chrono::offset::utc::UTC;
12+
13+
#[test]
14+
fn test_format() {
15+
let id_string = "thisismyname";
16+
let string_bytes : Vec<_> = id_string.bytes().collect();
17+
let mut bytes = [0; 12];
18+
19+
for i in 0..12 {
20+
bytes[i] = string_bytes[i];
21+
}
22+
23+
let id = ObjectId::with_bytes(bytes);
24+
let date = UTC::now();
25+
26+
let doc = doc! {
27+
"float" => 2.4,
28+
"string" => "hello",
29+
"array" => ["testing", 1],
30+
"doc" => {
31+
"fish" => "in",
32+
"a" => "barrel",
33+
"!" => 1
34+
},
35+
"bool" => true,
36+
"null" => (Bson::Null),
37+
"regexp" => (Bson::RegExp("s[ao]d".to_owned(), "i".to_owned())),
38+
"code" => (Bson::JavaScriptCode("function(x) { return x._id; }".to_owned())),
39+
"i32" => 12,
40+
"i64" => (-55),
41+
"timestamp" => (Bson::TimeStamp(229999444)),
42+
"binary" => (Bson::Binary(BinarySubtype::Md5, "thingies".to_owned().into_bytes())),
43+
"_id" => id,
44+
"date" => (Bson::UtcDatetime(date))
45+
};
46+
47+
let expected = format!("{{ float: 2.4, string: \"hello\", array: [\"testing\", 1], doc: {{ fish: \"in\", a: \"barrel\", !: 1 }}, bool: true, null: null, regexp: /s[ao]d/i, code: function(x) {{ return x._id; }}, i32: 12, i64: -55, timestamp: Timestamp(0, 229999444), binary: BinData(5, \"thingies\"), _id: ObjectId(\"{}\"), date: Date(\"{}\") }}", id_string, date);
48+
49+
assert_eq!(expected, format!("{}", doc));
50+
}

0 commit comments

Comments
 (0)