Skip to content

Commit 1c1fcca

Browse files
committed
Merge pull request #9 from saghm/format-display
Format Display for Bson
2 parents 1f66ffd + 3abfcef commit 1c1fcca

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

src/bson.rs

Lines changed: 54 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,57 @@ 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) => format!("BinData({}, 0x{})", u8::from(t), vec.to_hex()),
94+
&Bson::ObjectId(ref id) => {
95+
let mut vec = vec![];
96+
97+
for byte in id.bytes().iter() {
98+
vec.push(byte.to_owned());
99+
}
100+
101+
let string = unsafe { String::from_utf8_unchecked(vec) };
102+
format!("ObjectId(\"{}\")", string)
103+
}
104+
&Bson::UtcDatetime(date_time) => format!("Date(\"{}\")", date_time)
105+
};
106+
107+
fmt.write_str(&bson_string)
108+
}
109+
}
110+
57111
impl From<f32> for Bson {
58112
fn from(a: f32) -> Bson {
59113
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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
11
#[macro_use(bson, doc)]
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+
use rustc_serialize::hex::ToHex;
13+
14+
#[test]
15+
fn test_format() {
16+
let id_string = "thisismyname";
17+
let string_bytes : Vec<_> = id_string.bytes().collect();
18+
let mut bytes = [0; 12];
19+
20+
for i in 0..12 {
21+
bytes[i] = string_bytes[i];
22+
}
23+
24+
let id = ObjectId::with_bytes(bytes);
25+
let date = UTC::now();
26+
27+
let doc = doc! {
28+
"float" => 2.4,
29+
"string" => "hello",
30+
"array" => ["testing", 1],
31+
"doc" => {
32+
"fish" => "in",
33+
"a" => "barrel",
34+
"!" => 1
35+
},
36+
"bool" => true,
37+
"null" => (Bson::Null),
38+
"regexp" => (Bson::RegExp("s[ao]d".to_owned(), "i".to_owned())),
39+
"code" => (Bson::JavaScriptCode("function(x) { return x._id; }".to_owned())),
40+
"i32" => 12,
41+
"i64" => (-55),
42+
"timestamp" => (Bson::TimeStamp(229999444)),
43+
"binary" => (Bson::Binary(BinarySubtype::Md5, "thingies".to_owned().into_bytes())),
44+
"_id" => id,
45+
"date" => (Bson::UtcDatetime(date))
46+
};
47+
48+
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, 0x{}), _id: ObjectId(\"{}\"), date: Date(\"{}\") }}", "thingies".as_bytes().to_hex(), id_string, date);
49+
50+
assert_eq!(expected, format!("{}", doc));
51+
}

0 commit comments

Comments
 (0)