@@ -29,10 +29,11 @@ use chrono::{DateTime, Timelike, Utc};
2929use hex;
3030use serde_json:: Value ;
3131
32- use decimal128:: Decimal128 ;
33- use oid;
34- use ordered:: OrderedDocument ;
35- use spec:: { BinarySubtype , ElementType } ;
32+ #[ cfg( feature = "decimal128" ) ]
33+ use crate :: decimal128:: Decimal128 ;
34+ use crate :: oid;
35+ use crate :: ordered:: OrderedDocument ;
36+ use crate :: spec:: { BinarySubtype , ElementType } ;
3637
3738/// Possible BSON value types.
3839#[ derive( Clone , PartialEq ) ]
@@ -74,6 +75,7 @@ pub enum Bson {
7475 /// Symbol (Deprecated)
7576 Symbol ( String ) ,
7677 /// [128-bit decimal floating point](https://github.com/mongodb/specifications/blob/master/source/bson-decimal128/decimal128.rst)
78+ #[ cfg( feature = "decimal128" ) ]
7779 Decimal128 ( Decimal128 ) ,
7880}
7981
@@ -114,6 +116,7 @@ impl Debug for Bson {
114116 Bson :: ObjectId ( ref id) => write ! ( f, "ObjectId({:?})" , id) ,
115117 Bson :: UtcDatetime ( date_time) => write ! ( f, "UtcDatetime({:?})" , date_time) ,
116118 Bson :: Symbol ( ref sym) => write ! ( f, "Symbol({:?})" , sym) ,
119+ #[ cfg( feature = "decimal128" ) ]
117120 Bson :: Decimal128 ( ref d) => write ! ( f, "Decimal128({:?})" , d) ,
118121 }
119122 }
@@ -156,6 +159,7 @@ impl Display for Bson {
156159 Bson :: ObjectId ( ref id) => write ! ( fmt, "ObjectId(\" {}\" )" , id) ,
157160 Bson :: UtcDatetime ( date_time) => write ! ( fmt, "Date(\" {}\" )" , date_time) ,
158161 Bson :: Symbol ( ref sym) => write ! ( fmt, "Symbol(\" {}\" )" , sym) ,
162+ #[ cfg( feature = "decimal128" ) ]
159163 Bson :: Decimal128 ( ref d) => write ! ( fmt, "Decimal128({})" , d) ,
160164 }
161165 }
@@ -329,6 +333,7 @@ impl From<Bson> for Value {
329333 } ) ,
330334 // FIXME: Don't know what is the best way to encode Symbol type
331335 Bson :: Symbol ( v) => json ! ( { "$symbol" : v } ) ,
336+ #[ cfg( feature = "decimal128" ) ]
332337 Bson :: Decimal128 ( ref v) => json ! ( { "$numberDecimal" : v. to_string( ) } ) ,
333338 }
334339 }
@@ -354,6 +359,7 @@ impl Bson {
354359 Bson :: ObjectId ( ..) => ElementType :: ObjectId ,
355360 Bson :: UtcDatetime ( ..) => ElementType :: UtcDatetime ,
356361 Bson :: Symbol ( ..) => ElementType :: Symbol ,
362+ #[ cfg( feature = "decimal128" ) ]
357363 Bson :: Decimal128 ( ..) => ElementType :: Decimal128Bit ,
358364 }
359365 }
@@ -434,6 +440,7 @@ impl Bson {
434440 "$symbol" : v. to_owned( ) ,
435441 }
436442 }
443+ #[ cfg( feature = "decimal128" ) ]
437444 Bson :: Decimal128 ( ref v) => {
438445 doc ! {
439446 "$numberDecimal" => ( v. to_string( ) )
@@ -445,6 +452,7 @@ impl Bson {
445452
446453 /// Converts from extended format.
447454 /// This function is mainly used for [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
455+ #[ cfg( feature = "decimal128" ) ]
448456 #[ doc( hidden) ]
449457 pub fn from_extended_document ( values : Document ) -> Bson {
450458 if values. len ( ) == 2 {
@@ -480,6 +488,43 @@ impl Bson {
480488
481489 Bson :: Document ( values)
482490 }
491+
492+ /// Converts from extended format.
493+ /// This function is mainly used for [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
494+ #[ cfg( not( feature = "decimal128" ) ) ]
495+ #[ doc( hidden) ]
496+ pub fn from_extended_document ( values : Document ) -> Bson {
497+ if values. len ( ) == 2 {
498+ if let ( Ok ( pat) , Ok ( opt) ) = ( values. get_str ( "$regex" ) , values. get_str ( "$options" ) ) {
499+ return Bson :: RegExp ( pat. to_owned ( ) , opt. to_owned ( ) ) ;
500+ } else if let ( Ok ( code) , Ok ( scope) ) = ( values. get_str ( "$code" ) , values. get_document ( "$scope" ) ) {
501+ return Bson :: JavaScriptCodeWithScope ( code. to_owned ( ) , scope. to_owned ( ) ) ;
502+ } else if let ( Ok ( t) , Ok ( i) ) = ( values. get_i32 ( "t" ) , values. get_i32 ( "i" ) ) {
503+ let timestamp = ( ( t as i64 ) << 32 ) + ( i as i64 ) ;
504+ return Bson :: TimeStamp ( timestamp) ;
505+ } else if let ( Ok ( t) , Ok ( i) ) = ( values. get_i64 ( "t" ) , values. get_i64 ( "i" ) ) {
506+ let timestamp = ( t << 32 ) + i;
507+ return Bson :: TimeStamp ( timestamp) ;
508+ } else if let ( Ok ( hex) , Ok ( t) ) = ( values. get_str ( "$binary" ) , values. get_i64 ( "type" ) ) {
509+ let ttype = t as u8 ;
510+ return Bson :: Binary ( From :: from ( ttype) , hex:: decode ( hex. as_bytes ( ) ) . expect ( "$binary value is not a valid Hex encoded bytes" ) ) ;
511+ }
512+ } else if values. len ( ) == 1 {
513+ if let Ok ( code) = values. get_str ( "$code" ) {
514+ return Bson :: JavaScriptCode ( code. to_owned ( ) ) ;
515+ } else if let Ok ( hex) = values. get_str ( "$oid" ) {
516+ return Bson :: ObjectId ( oid:: ObjectId :: with_string ( hex) . unwrap ( ) ) ;
517+ } else if let Ok ( long) = values. get_document ( "$date" )
518+ . and_then ( |inner| inner. get_i64 ( "$numberLong" ) )
519+ {
520+ return Bson :: UtcDatetime ( Utc . timestamp ( long / 1000 , ( ( long % 1000 ) * 1_000_000 ) as u32 ) ) ;
521+ } else if let Ok ( sym) = values. get_str ( "$symbol" ) {
522+ return Bson :: Symbol ( sym. to_owned ( ) ) ;
523+ }
524+ }
525+
526+ Bson :: Document ( values)
527+ }
483528}
484529
485530/// Value helpers
0 commit comments