Skip to content

Commit 4a056c2

Browse files
jcdyerzonyitoo
authored andcommitted
Add more Bson From<> implementations for better ergonomics. (#130)
1 parent 8d1a34e commit 4a056c2

File tree

2 files changed

+85
-17
lines changed

2 files changed

+85
-17
lines changed

src/bson.rs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl From<f64> for Bson {
177177
}
178178
}
179179

180-
impl<'a> From<&'a str> for Bson {
180+
impl From<&str> for Bson {
181181
fn from(s: &str) -> Bson {
182182
Bson::String(s.to_owned())
183183
}
@@ -189,18 +189,6 @@ impl From<String> for Bson {
189189
}
190190
}
191191

192-
impl<'a> From<&'a String> for Bson {
193-
fn from(a: &'a String) -> Bson {
194-
Bson::String(a.to_owned())
195-
}
196-
}
197-
198-
impl From<Array> for Bson {
199-
fn from(a: Array) -> Bson {
200-
Bson::Array(a)
201-
}
202-
}
203-
204192
impl From<Document> for Bson {
205193
fn from(a: Document) -> Bson {
206194
Bson::Document(a)
@@ -231,6 +219,49 @@ impl From<(BinarySubtype, Vec<u8>)> for Bson {
231219
}
232220
}
233221

222+
impl<T> From<&T> for Bson
223+
where
224+
T: Clone + Into<Bson>
225+
{
226+
fn from(t: &T) -> Bson {
227+
t.clone().into()
228+
}
229+
}
230+
231+
impl<T> From<Vec<T>> for Bson
232+
where
233+
T: Into<Bson>
234+
{
235+
fn from(v: Vec<T>) -> Bson {
236+
Bson::Array(v.into_iter().map(|val| val.into()).collect())
237+
}
238+
}
239+
240+
impl<T> From<&[T]> for Bson
241+
where
242+
T: Clone + Into<Bson>
243+
{
244+
fn from(s: &[T]) -> Bson {
245+
Bson::Array(s.into_iter().cloned().map(|val| val.into()).collect())
246+
}
247+
}
248+
249+
impl<T: Into<Bson>> ::std::iter::FromIterator<T> for Bson {
250+
/// # Examples
251+
///
252+
/// ```
253+
/// use std::iter::FromIterator;
254+
/// use bson::Bson;
255+
///
256+
/// let x: Bson = Bson::from_iter(vec!["lorem", "ipsum", "dolor"]);
257+
/// // or
258+
/// let x: Bson = vec!["lorem", "ipsum", "dolor"].into_iter().collect();
259+
/// ```
260+
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
261+
Bson::Array(iter.into_iter().map(Into::into).collect())
262+
}
263+
}
264+
234265
impl From<i32> for Bson {
235266
fn from(a: i32) -> Bson {
236267
Bson::I32(a)
@@ -719,8 +750,7 @@ impl Bson {
719750
/// Just a helper for convenience
720751
///
721752
/// ```rust,ignore
722-
/// #[macro_use]
723-
/// extern crate serde_derive;
753+
/// use serde::{Serialize, Deserialize};
724754
/// extern crate bson;
725755
/// use bson::TimeStamp;
726756
///

tests/modules/bson.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
extern crate serde_json;
22

3-
use self::serde_json::Value;
4-
use bson::{Bson, Document};
3+
use self::serde_json::{Value, json};
4+
use bson::{Bson, Document, oid::ObjectId, spec::BinarySubtype};
55

66
#[test]
77
fn to_json() {
88
let mut doc = Document::new();
9+
doc.insert("_id", Bson::ObjectId(ObjectId::with_bytes(*b"abcdefghijkl")));
910
doc.insert("first", Bson::I32(1));
1011
doc.insert("second", Bson::String("foo".to_owned()));
1112
doc.insert("alphanumeric", Bson::String("bar".to_owned()));
@@ -14,6 +15,12 @@ fn to_json() {
1415
assert!(data.is_object());
1516
let obj = data.as_object().unwrap();
1617

18+
let id = obj.get("_id").unwrap();
19+
assert!(id.is_object());
20+
let id_val = id.get("$oid").unwrap();
21+
assert!(id_val.is_string());
22+
assert_eq!(id_val, "6162636465666768696a6b6c");
23+
1724
let first = obj.get("first").unwrap();
1825
assert!(first.is_number());
1926
assert_eq!(first.as_i64().unwrap(), 1);
@@ -39,3 +46,34 @@ fn document_default() {
3946
assert_eq!(doc1.keys().count(), 0);
4047
assert_eq!(doc1, Document::new());
4148
}
49+
50+
#[test]
51+
fn from_impls() {
52+
assert_eq!(Bson::from(1.5f32), Bson::FloatingPoint(1.5));
53+
assert_eq!(Bson::from(2.25f64), Bson::FloatingPoint(2.25));
54+
assert_eq!(Bson::from("data"), Bson::String(String::from("data")));
55+
assert_eq!(Bson::from(String::from("data")), Bson::String(String::from("data")));
56+
assert_eq!(Bson::from(doc!{}), Bson::Document(Document::new()));
57+
assert_eq!(Bson::from(false), Bson::Boolean(false));
58+
assert_eq!(Bson::from((String::from("\\s+$"), String::from("i"))), Bson::RegExp(String::from("\\s+$"), String::from("i")));
59+
assert_eq!(Bson::from((String::from("alert(\"hi\");"), doc!{})), Bson::JavaScriptCodeWithScope(String::from("alert(\"hi\");"), doc!{}));
60+
//
61+
assert_eq!(Bson::from((BinarySubtype::Generic, vec![1, 2, 3])), Bson::Binary(BinarySubtype::Generic, vec![1, 2, 3]));
62+
assert_eq!(Bson::from(-48i32), Bson::I32(-48));
63+
assert_eq!(Bson::from(-96i64), Bson::I64(-96));
64+
assert_eq!(Bson::from(152u32), Bson::I32(152));
65+
assert_eq!(Bson::from(4096u64), Bson::I64(4096));
66+
67+
let oid = ObjectId::new().unwrap();
68+
assert_eq!(Bson::from(b"abcdefghijkl"), Bson::ObjectId(ObjectId::with_bytes(*b"abcdefghijkl")));
69+
assert_eq!(Bson::from(oid.clone()), Bson::ObjectId(oid.clone()));
70+
assert_eq!(Bson::from(vec![1, 2, 3]), Bson::Array(vec![Bson::I32(1), Bson::I32(2), Bson::I32(3)]));
71+
assert_eq!(Bson::from(json!({"_id": {"$oid": oid.to_hex()}, "name": ["bson-rs"]})), Bson::Document(doc!{"_id": &oid, "name": ["bson-rs"]}));
72+
73+
// References
74+
assert_eq!(Bson::from(&24i32), Bson::I32(24));
75+
assert_eq!(Bson::from(&String::from("data")), Bson::String(String::from("data")));
76+
assert_eq!(Bson::from(&oid), Bson::ObjectId(oid));
77+
assert_eq!(Bson::from(&doc!{"a": "b"}), Bson::Document(doc!{"a": "b"}));
78+
79+
}

0 commit comments

Comments
 (0)