Skip to content

Commit 728a31b

Browse files
authored
Merge pull request #59 from zonyitoo/feature-bson-getter
add getter helpers for Bson, correct implementation for #57
2 parents 273f2ef + 4430ce8 commit 728a31b

File tree

1 file changed

+150
-16
lines changed

1 file changed

+150
-16
lines changed

src/bson.rs

+150-16
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,41 @@ use spec::{ElementType, BinarySubtype};
3535
/// Possible BSON value types.
3636
#[derive(Clone, PartialEq)]
3737
pub enum Bson {
38+
/// 64-bit binary floating point
3839
FloatingPoint(f64),
40+
/// UTF-8 string
3941
String(String),
42+
/// Array
4043
Array(Array),
44+
/// Embedded document
4145
Document(Document),
46+
/// Boolean value
4247
Boolean(bool),
48+
/// Null value
4349
Null,
50+
/// Regular expression - The first cstring is the regex pattern, the second is the regex options string.
51+
/// Options are identified by characters, which must be stored in alphabetical order.
52+
/// Valid options are 'i' for case insensitive matching, 'm' for multiline matching, 'x' for verbose mode,
53+
/// 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode ('.' matches everything), and 'u' to
54+
/// make \w, \W, etc. match unicode.
4455
RegExp(String, String),
56+
/// JavaScript code
4557
JavaScriptCode(String),
58+
/// JavaScript code w/ scope
4659
JavaScriptCodeWithScope(String, Document),
60+
/// 32-bit integer
4761
I32(i32),
62+
/// 64-bit integer
4863
I64(i64),
64+
/// Timestamp
4965
TimeStamp(i64),
66+
/// Binary data
5067
Binary(BinarySubtype, Vec<u8>),
68+
/// [ObjectId](http://dochub.mongodb.org/core/objectids)
5169
ObjectId(oid::ObjectId),
70+
/// UTC datetime
5271
UtcDatetime(DateTime<UTC>),
72+
/// Symbol (Deprecated)
5373
Symbol(String),
5474
}
5575

@@ -80,7 +100,9 @@ impl Debug for Bson {
80100

81101
write!(f, "TimeStamp({}, {})", time, inc)
82102
}
83-
&Bson::Binary(t, ref vec) => write!(f, "BinData({}, 0x{})", u8::from(t), hex::encode(vec)),
103+
&Bson::Binary(t, ref vec) => {
104+
write!(f, "BinData({}, 0x{})", u8::from(t), hex::encode(vec))
105+
}
84106
&Bson::ObjectId(ref id) => write!(f, "ObjectId({:?})", id),
85107
&Bson::UtcDatetime(date_time) => write!(f, "UtcDatetime({:?})", date_time),
86108
&Bson::Symbol(ref sym) => write!(f, "Symbol({:?})", sym),
@@ -275,17 +297,19 @@ impl Bson {
275297
&Bson::Document(ref v) => json!(v),
276298
&Bson::Boolean(v) => json!(v),
277299
&Bson::Null => Value::Null,
278-
&Bson::RegExp(ref pat, ref opt) => json!({
279-
"$regex": pat,
280-
"$options": opt
281-
}),
300+
&Bson::RegExp(ref pat, ref opt) => {
301+
json!({
302+
"$regex": pat,
303+
"$options": opt
304+
})
305+
}
282306
&Bson::JavaScriptCode(ref code) => json!({"$code": code}),
283307
&Bson::JavaScriptCodeWithScope(ref code, ref scope) => {
284308
json!({
285309
"$code": code,
286310
"scope": scope
287311
})
288-
},
312+
}
289313
&Bson::I32(v) => v.into(),
290314
&Bson::I64(v) => v.into(),
291315
&Bson::TimeStamp(v) => {
@@ -296,32 +320,36 @@ impl Bson {
296320
"t": time,
297321
"i": inc
298322
})
299-
},
323+
}
300324
&Bson::Binary(t, ref v) => {
301325
let tval: u8 = From::from(t);
302326
json!({
303327
"type": tval,
304328
"$binary": hex::encode(v)
305329
})
306-
},
330+
}
307331
&Bson::ObjectId(ref v) => json!({"$oid": v.to_string()}),
308-
&Bson::UtcDatetime(ref v) => json!({
332+
&Bson::UtcDatetime(ref v) => {
333+
json!({
309334
"$date": {
310335
"$numberLong": (v.timestamp() * 1000) + ((v.nanosecond() / 1000000) as i64)
311336
}
312-
}),
337+
})
338+
}
313339
// FIXME: Don't know what is the best way to encode Symbol type
314-
&Bson::Symbol(ref v) => json!({"$symbol": v})
340+
&Bson::Symbol(ref v) => json!({"$symbol": v}),
315341
}
316342
}
317343

318344
/// Create a `Bson` from a `Json`.
319345
pub fn from_json(j: &Value) -> Bson {
320346
match j {
321-
&Value::Number(ref x) =>
322-
x.as_i64().map(Bson::from)
323-
.or_else(|| x.as_f64().map(Bson::from))
324-
.expect(&format!("Invalid number value: {}", x)),
347+
&Value::Number(ref x) => {
348+
x.as_i64()
349+
.map(Bson::from)
350+
.or_else(|| x.as_f64().map(Bson::from))
351+
.expect(&format!("Invalid number value: {}", x))
352+
}
325353
&Value::String(ref x) => x.into(),
326354
&Value::Bool(x) => x.into(),
327355
&Value::Array(ref x) => Bson::Array(x.iter().map(Bson::from_json).collect()),
@@ -334,6 +362,9 @@ impl Bson {
334362
}
335363
}
336364

365+
/// Converts to extended format.
366+
/// This function mainly used for [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
367+
#[doc(hidden)]
337368
pub fn to_extended_document(&self) -> Document {
338369
match *self {
339370
Bson::RegExp(ref pat, ref opt) => {
@@ -390,6 +421,9 @@ impl Bson {
390421
}
391422
}
392423

424+
/// Converts from extended format.
425+
/// This function mainly used for [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
426+
#[doc(hidden)]
393427
pub fn from_extended_document(values: Document) -> Bson {
394428
if values.len() == 2 {
395429
if let (Ok(pat), Ok(opt)) = (values.get_str("$regex"), values.get_str("$options")) {
@@ -409,7 +443,8 @@ impl Bson {
409443

410444
} else if let (Ok(hex), Ok(t)) = (values.get_str("$binary"), values.get_i64("type")) {
411445
let ttype = t as u8;
412-
return Bson::Binary(From::from(ttype), hex::decode(hex.to_uppercase().as_bytes()).unwrap());
446+
return Bson::Binary(From::from(ttype),
447+
hex::decode(hex.to_uppercase().as_bytes()).unwrap());
413448
}
414449

415450
} else if values.len() == 1 {
@@ -430,3 +465,102 @@ impl Bson {
430465
Bson::Document(values)
431466
}
432467
}
468+
469+
/// Value helpers
470+
impl Bson {
471+
/// If `Bson` is `FloatingPoint`, return its value. Returns `None` otherwise
472+
pub fn as_f64(&self) -> Option<f64> {
473+
match *self {
474+
Bson::FloatingPoint(ref v) => Some(*v),
475+
_ => None,
476+
}
477+
}
478+
479+
/// If `Bson` is `String`, return its value. Returns `None` otherwise
480+
pub fn as_str(&self) -> Option<&str> {
481+
match *self {
482+
Bson::String(ref s) => Some(s),
483+
_ => None,
484+
}
485+
}
486+
487+
/// If `Bson` is `Array`, return its value. Returns `None` otherwise
488+
pub fn as_array(&self) -> Option<&Array> {
489+
match *self {
490+
Bson::Array(ref v) => Some(v),
491+
_ => None,
492+
}
493+
}
494+
495+
/// If `Bson` is `Document`, return its value. Returns `None` otherwise
496+
pub fn as_document(&self) -> Option<&Document> {
497+
match *self {
498+
Bson::Document(ref v) => Some(v),
499+
_ => None,
500+
}
501+
}
502+
503+
/// If `Bson` is `Boolean`, return its value. Returns `None` otherwise
504+
pub fn as_bool(&self) -> Option<bool> {
505+
match *self {
506+
Bson::Boolean(ref v) => Some(*v),
507+
_ => None,
508+
}
509+
}
510+
511+
/// If `Bson` is `I32`, return its value. Returns `None` otherwise
512+
pub fn as_i32(&self) -> Option<i32> {
513+
match *self {
514+
Bson::I32(ref v) => Some(*v),
515+
_ => None,
516+
}
517+
}
518+
519+
/// If `Bson` is `I64`, return its value. Returns `None` otherwise
520+
pub fn as_i64(&self) -> Option<i64> {
521+
match *self {
522+
Bson::I64(ref v) => Some(*v),
523+
_ => None,
524+
}
525+
}
526+
527+
/// If `Bson` is `Objectid`, return its value. Returns `None` otherwise
528+
pub fn as_object_id(&self) -> Option<&oid::ObjectId> {
529+
match *self {
530+
Bson::ObjectId(ref v) => Some(v),
531+
_ => None,
532+
}
533+
}
534+
535+
/// If `Bson` is `UtcDateTime`, return its value. Returns `None` otherwise
536+
pub fn as_utc_date_time(&self) -> Option<&DateTime<UTC>> {
537+
match *self {
538+
Bson::UtcDatetime(ref v) => Some(v),
539+
_ => None,
540+
}
541+
}
542+
543+
/// If `Bson` is `Symbol`, return its value. Returns `None` otherwise
544+
pub fn as_symbol(&self) -> Option<&str> {
545+
match *self {
546+
Bson::Symbol(ref v) => Some(v),
547+
_ => None,
548+
}
549+
}
550+
551+
/// If `Bson` is `TimeStamp`, return its value. Returns `None` otherwise
552+
pub fn as_timestamp(&self) -> Option<i64> {
553+
match *self {
554+
Bson::TimeStamp(ref v) => Some(*v),
555+
_ => None,
556+
}
557+
}
558+
559+
/// If `Bson` is `Null`, return its value. Returns `None` otherwise
560+
pub fn as_null(&self) -> Option<()> {
561+
match *self {
562+
Bson::Null => Some(()),
563+
_ => None,
564+
}
565+
}
566+
}

0 commit comments

Comments
 (0)