@@ -35,21 +35,41 @@ use spec::{ElementType, BinarySubtype};
35
35
/// Possible BSON value types.
36
36
#[ derive( Clone , PartialEq ) ]
37
37
pub enum Bson {
38
+ /// 64-bit binary floating point
38
39
FloatingPoint ( f64 ) ,
40
+ /// UTF-8 string
39
41
String ( String ) ,
42
+ /// Array
40
43
Array ( Array ) ,
44
+ /// Embedded document
41
45
Document ( Document ) ,
46
+ /// Boolean value
42
47
Boolean ( bool ) ,
48
+ /// Null value
43
49
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.
44
55
RegExp ( String , String ) ,
56
+ /// JavaScript code
45
57
JavaScriptCode ( String ) ,
58
+ /// JavaScript code w/ scope
46
59
JavaScriptCodeWithScope ( String , Document ) ,
60
+ /// 32-bit integer
47
61
I32 ( i32 ) ,
62
+ /// 64-bit integer
48
63
I64 ( i64 ) ,
64
+ /// Timestamp
49
65
TimeStamp ( i64 ) ,
66
+ /// Binary data
50
67
Binary ( BinarySubtype , Vec < u8 > ) ,
68
+ /// [ObjectId](http://dochub.mongodb.org/core/objectids)
51
69
ObjectId ( oid:: ObjectId ) ,
70
+ /// UTC datetime
52
71
UtcDatetime ( DateTime < UTC > ) ,
72
+ /// Symbol (Deprecated)
53
73
Symbol ( String ) ,
54
74
}
55
75
@@ -80,7 +100,9 @@ impl Debug for Bson {
80
100
81
101
write ! ( f, "TimeStamp({}, {})" , time, inc)
82
102
}
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
+ }
84
106
& Bson :: ObjectId ( ref id) => write ! ( f, "ObjectId({:?})" , id) ,
85
107
& Bson :: UtcDatetime ( date_time) => write ! ( f, "UtcDatetime({:?})" , date_time) ,
86
108
& Bson :: Symbol ( ref sym) => write ! ( f, "Symbol({:?})" , sym) ,
@@ -275,17 +297,19 @@ impl Bson {
275
297
& Bson :: Document ( ref v) => json ! ( v) ,
276
298
& Bson :: Boolean ( v) => json ! ( v) ,
277
299
& 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
+ }
282
306
& Bson :: JavaScriptCode ( ref code) => json ! ( { "$code" : code} ) ,
283
307
& Bson :: JavaScriptCodeWithScope ( ref code, ref scope) => {
284
308
json ! ( {
285
309
"$code" : code,
286
310
"scope" : scope
287
311
} )
288
- } ,
312
+ }
289
313
& Bson :: I32 ( v) => v. into ( ) ,
290
314
& Bson :: I64 ( v) => v. into ( ) ,
291
315
& Bson :: TimeStamp ( v) => {
@@ -296,32 +320,36 @@ impl Bson {
296
320
"t" : time,
297
321
"i" : inc
298
322
} )
299
- } ,
323
+ }
300
324
& Bson :: Binary ( t, ref v) => {
301
325
let tval: u8 = From :: from ( t) ;
302
326
json ! ( {
303
327
"type" : tval,
304
328
"$binary" : hex:: encode( v)
305
329
} )
306
- } ,
330
+ }
307
331
& Bson :: ObjectId ( ref v) => json ! ( { "$oid" : v. to_string( ) } ) ,
308
- & Bson :: UtcDatetime ( ref v) => json ! ( {
332
+ & Bson :: UtcDatetime ( ref v) => {
333
+ json ! ( {
309
334
"$date" : {
310
335
"$numberLong" : ( v. timestamp( ) * 1000 ) + ( ( v. nanosecond( ) / 1000000 ) as i64 )
311
336
}
312
- } ) ,
337
+ } )
338
+ }
313
339
// 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} ) ,
315
341
}
316
342
}
317
343
318
344
/// Create a `Bson` from a `Json`.
319
345
pub fn from_json ( j : & Value ) -> Bson {
320
346
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
+ }
325
353
& Value :: String ( ref x) => x. into ( ) ,
326
354
& Value :: Bool ( x) => x. into ( ) ,
327
355
& Value :: Array ( ref x) => Bson :: Array ( x. iter ( ) . map ( Bson :: from_json) . collect ( ) ) ,
@@ -334,6 +362,9 @@ impl Bson {
334
362
}
335
363
}
336
364
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) ]
337
368
pub fn to_extended_document ( & self ) -> Document {
338
369
match * self {
339
370
Bson :: RegExp ( ref pat, ref opt) => {
@@ -390,6 +421,9 @@ impl Bson {
390
421
}
391
422
}
392
423
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) ]
393
427
pub fn from_extended_document ( values : Document ) -> Bson {
394
428
if values. len ( ) == 2 {
395
429
if let ( Ok ( pat) , Ok ( opt) ) = ( values. get_str ( "$regex" ) , values. get_str ( "$options" ) ) {
@@ -409,7 +443,8 @@ impl Bson {
409
443
410
444
} else if let ( Ok ( hex) , Ok ( t) ) = ( values. get_str ( "$binary" ) , values. get_i64 ( "type" ) ) {
411
445
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 ( ) ) ;
413
448
}
414
449
415
450
} else if values. len ( ) == 1 {
@@ -430,3 +465,102 @@ impl Bson {
430
465
Bson :: Document ( values)
431
466
}
432
467
}
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