Skip to content

Commit cc4b157

Browse files
kyeahzonyitoo
authored andcommitted
Implement From/Into traits for Value (#63)
Implement From/Into traits for Value
1 parent ac63df3 commit cc4b157

File tree

1 file changed

+81
-65
lines changed

1 file changed

+81
-65
lines changed

src/bson.rs

+81-65
Original file line numberDiff line numberDiff line change
@@ -263,103 +263,119 @@ impl From<DateTime<UTC>> for Bson {
263263
}
264264
}
265265

266-
impl Bson {
267-
/// Get the `ElementType` of this value.
268-
pub fn element_type(&self) -> ElementType {
269-
match self {
270-
&Bson::FloatingPoint(..) => ElementType::FloatingPoint,
271-
&Bson::String(..) => ElementType::Utf8String,
272-
&Bson::Array(..) => ElementType::Array,
273-
&Bson::Document(..) => ElementType::EmbeddedDocument,
274-
&Bson::Boolean(..) => ElementType::Boolean,
275-
&Bson::Null => ElementType::NullValue,
276-
&Bson::RegExp(..) => ElementType::RegularExpression,
277-
&Bson::JavaScriptCode(..) => ElementType::JavaScriptCode,
278-
&Bson::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
279-
&Bson::I32(..) => ElementType::Integer32Bit,
280-
&Bson::I64(..) => ElementType::Integer64Bit,
281-
&Bson::TimeStamp(..) => ElementType::TimeStamp,
282-
&Bson::Binary(..) => ElementType::Binary,
283-
&Bson::ObjectId(..) => ElementType::ObjectId,
284-
&Bson::UtcDatetime(..) => ElementType::UtcDatetime,
285-
&Bson::Symbol(..) => ElementType::Symbol,
266+
impl From<Value> for Bson {
267+
fn from(a: Value) -> Bson {
268+
match a {
269+
Value::Number(x) =>
270+
x.as_i64().map(Bson::from)
271+
.or(x.as_u64().map(Bson::from))
272+
.expect(&format!("Invalid number value: {}", x)),
273+
Value::String(x) => x.into(),
274+
Value::Bool(x) => x.into(),
275+
Value::Array(x) => Bson::Array(x.into_iter().map(Bson::from).collect()),
276+
Value::Object(x) => {
277+
Bson::from_extended_document(x.into_iter()
278+
.map(|(k, v)| (k.clone(), v.into()))
279+
.collect())
280+
}
281+
Value::Null => Bson::Null,
286282
}
287283
}
284+
}
288285

289-
/// Convert this value to the best approximate `Json`.
290-
pub fn to_json(&self) -> Value {
286+
impl Into<Value> for Bson {
287+
fn into(self) -> Value {
291288
match self {
292-
&Bson::FloatingPoint(v) => json!(v),
293-
&Bson::String(ref v) => json!(v),
294-
&Bson::Array(ref v) => json!(v),
295-
&Bson::Document(ref v) => json!(v),
296-
&Bson::Boolean(v) => json!(v),
297-
&Bson::Null => Value::Null,
298-
&Bson::RegExp(ref pat, ref opt) => {
299-
json!({
300-
"$regex": pat,
301-
"$options": opt
302-
})
303-
}
304-
&Bson::JavaScriptCode(ref code) => json!({"$code": code}),
305-
&Bson::JavaScriptCodeWithScope(ref code, ref scope) => {
289+
Bson::FloatingPoint(v) => json!(v),
290+
Bson::String(v) => json!(v),
291+
Bson::Array(v) => json!(v),
292+
Bson::Document(v) => json!(v),
293+
Bson::Boolean(v) => json!(v),
294+
Bson::Null => Value::Null,
295+
Bson::RegExp(pat, opt) => json!({
296+
"$regex": pat,
297+
"$options": opt
298+
}),
299+
Bson::JavaScriptCode(code) => json!({"$code": code}),
300+
Bson::JavaScriptCodeWithScope(code, scope) => {
306301
json!({
307302
"$code": code,
308303
"scope": scope
309304
})
310305
}
311-
&Bson::I32(v) => v.into(),
312-
&Bson::I64(v) => v.into(),
313-
&Bson::TimeStamp(v) => {
306+
Bson::I32(v) => v.into(),
307+
Bson::I64(v) => v.into(),
308+
Bson::TimeStamp(v) => {
314309
let time = v >> 32;
315310
let inc = v & 0x0000FFFF;
316-
317311
json!({
318312
"t": time,
319313
"i": inc
320314
})
321315
}
322-
&Bson::Binary(t, ref v) => {
316+
Bson::Binary(t, ref v) => {
323317
let tval: u8 = From::from(t);
324318
json!({
325319
"type": tval,
326320
"$binary": v.to_hex()
327321
})
328322
}
329-
&Bson::ObjectId(ref v) => json!({"$oid": v.to_string()}),
330-
&Bson::UtcDatetime(ref v) => {
331-
json!({
323+
Bson::ObjectId(v) => json!({"$oid": v.to_string()}),
324+
Bson::UtcDatetime(v) => json!({
332325
"$date": {
333326
"$numberLong": (v.timestamp() * 1000) + ((v.nanosecond() / 1000000) as i64)
334327
}
335-
})
336-
}
328+
}),
337329
// FIXME: Don't know what is the best way to encode Symbol type
338-
&Bson::Symbol(ref v) => json!({"$symbol": v}),
330+
Bson::Symbol(v) => json!({"$symbol": v})
339331
}
340332
}
333+
}
341334

342-
/// Create a `Bson` from a `Json`.
343-
pub fn from_json(j: &Value) -> Bson {
344-
match j {
345-
&Value::Number(ref x) => {
346-
x.as_i64()
347-
.map(Bson::from)
348-
.or_else(|| x.as_f64().map(Bson::from))
349-
.expect(&format!("Invalid number value: {}", x))
350-
}
351-
&Value::String(ref x) => x.into(),
352-
&Value::Bool(x) => x.into(),
353-
&Value::Array(ref x) => Bson::Array(x.iter().map(Bson::from_json).collect()),
354-
&Value::Object(ref x) => {
355-
Bson::from_extended_document(x.iter()
356-
.map(|(k, v)| (k.clone(), Bson::from_json(v)))
357-
.collect())
358-
}
359-
&Value::Null => Bson::Null,
335+
impl Bson {
336+
/// Get the `ElementType` of this value.
337+
pub fn element_type(&self) -> ElementType {
338+
match self {
339+
&Bson::FloatingPoint(..) => ElementType::FloatingPoint,
340+
&Bson::String(..) => ElementType::Utf8String,
341+
&Bson::Array(..) => ElementType::Array,
342+
&Bson::Document(..) => ElementType::EmbeddedDocument,
343+
&Bson::Boolean(..) => ElementType::Boolean,
344+
&Bson::Null => ElementType::NullValue,
345+
&Bson::RegExp(..) => ElementType::RegularExpression,
346+
&Bson::JavaScriptCode(..) => ElementType::JavaScriptCode,
347+
&Bson::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
348+
&Bson::I32(..) => ElementType::Integer32Bit,
349+
&Bson::I64(..) => ElementType::Integer64Bit,
350+
&Bson::TimeStamp(..) => ElementType::TimeStamp,
351+
&Bson::Binary(..) => ElementType::Binary,
352+
&Bson::ObjectId(..) => ElementType::ObjectId,
353+
&Bson::UtcDatetime(..) => ElementType::UtcDatetime,
354+
&Bson::Symbol(..) => ElementType::Symbol,
360355
}
361356
}
362357

358+
/// Clones the bson and returns the representative serde_json Value.
359+
/// The json will be in [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
360+
#[deprecated(since="0.5.1", note="use bson.clone().into() instead")]
361+
pub fn to_json(&self) -> Value {
362+
self.clone().into()
363+
}
364+
365+
/// Consumes the bson and returns the representative serde_json Value.
366+
/// The json will be in [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
367+
#[deprecated(since="0.5.1", note="use bson.into() instead")]
368+
pub fn into_json(self) -> Value {
369+
self.into()
370+
}
371+
372+
/// Consumes the serde_json Value and returns the representative bson.
373+
/// The json should be in [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
374+
#[deprecated(since="0.5.1", note="use json.into() instead")]
375+
pub fn from_json(val: Value) -> Bson {
376+
val.into()
377+
}
378+
363379
/// Converts to extended format.
364380
/// This function mainly used for [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
365381
#[doc(hidden)]

0 commit comments

Comments
 (0)