Skip to content

Commit 00edb6e

Browse files
committed
Bump version to v0.14.0, edition=2018, add decimal128 feature gate
1 parent 323cafa commit 00edb6e

File tree

16 files changed

+175
-92
lines changed

16 files changed

+175
-92
lines changed

Cargo.toml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bson"
3-
version = "0.13.1"
3+
version = "0.14.0"
44
authors = [
55
"Y. T. Chung <[email protected]>",
66
"Kevin Yeh <[email protected]>"
@@ -10,12 +10,15 @@ license = "MIT"
1010
readme = "README.md"
1111
homepage = "https://github.com/zonyitoo/bson-rs"
1212
documentation = "https://docs.rs/crate/bson"
13+
edition = "2018"
1314

1415
[features]
1516
# no features by default
1617
default = []
1718
# attempt to encode unsigned types in signed types
1819
u2i = []
20+
# Decimal128 in BSON 1.1
21+
decimal128 = ["decimal"]
1922

2023
[lib]
2124
name = "bson"
@@ -31,7 +34,7 @@ time = "0.1"
3134
linked-hash-map = "0.5"
3235
hex = "0.3"
3336
md5 = "0.6"
34-
decimal = "2.0.4"
37+
decimal = { version = "2.0.4", optional = true }
3538

3639
[dev-dependencies]
3740
assert_matches = "1.2"

src/bson.rs

+49-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ use chrono::{DateTime, Timelike, Utc};
2929
use hex;
3030
use 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

src/decoder/error.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl error::Error for DecoderError {
9494
DecoderError::AmbiguousTimestamp(..) => "ambiguous local time",
9595
}
9696
}
97-
fn cause(&self) -> Option<&error::Error> {
97+
fn cause(&self) -> Option<&dyn error::Error> {
9898
match *self {
9999
DecoderError::IoError(ref inner) => Some(inner),
100100
DecoderError::FromUtf8Error(ref inner) => Some(inner),
@@ -108,15 +108,15 @@ impl de::Error for DecoderError {
108108
DecoderError::Unknown(msg.to_string())
109109
}
110110

111-
fn invalid_type(_unexp: Unexpected, exp: &Expected) -> DecoderError {
111+
fn invalid_type(_unexp: Unexpected, exp: &dyn Expected) -> DecoderError {
112112
DecoderError::InvalidType(exp.to_string())
113113
}
114114

115-
fn invalid_value(_unexp: Unexpected, exp: &Expected) -> DecoderError {
115+
fn invalid_value(_unexp: Unexpected, exp: &dyn Expected) -> DecoderError {
116116
DecoderError::InvalidValue(exp.to_string())
117117
}
118118

119-
fn invalid_length(len: usize, exp: &Expected) -> DecoderError {
119+
fn invalid_length(len: usize, exp: &dyn Expected) -> DecoderError {
120120
DecoderError::InvalidLength(len, exp.to_string())
121121
}
122122

src/decoder/mod.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ pub use self::error::{DecoderError, DecoderResult};
2828
pub use self::serde::Decoder;
2929

3030
use std::io::Read;
31-
use std::mem;
3231

3332
use byteorder::{LittleEndian, ReadBytesExt};
3433
use chrono::offset::{LocalResult, TimeZone};
3534
use chrono::Utc;
36-
use decimal128::Decimal128;
3735

38-
use bson::{Array, Bson, Document};
39-
use oid;
40-
use spec::{self, BinarySubtype};
36+
use crate::bson::{Array, Bson, Document};
37+
#[cfg(feature = "decimal128")]
38+
use crate::decimal128::Decimal128;
39+
use crate::oid;
40+
use crate::spec::{self, BinarySubtype};
4141

42-
use serde::de::Deserialize;
42+
use ::serde::de::Deserialize;
4343

4444
const MAX_BSON_SIZE: i32 = 16 * 1024 * 1024;
4545

@@ -89,10 +89,13 @@ fn read_i64<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<i64> {
8989
reader.read_i64::<LittleEndian>().map_err(From::from)
9090
}
9191

92+
#[cfg(feature = "decimal128")]
9293
#[inline]
9394
fn read_f128<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<Decimal128> {
94-
let mut local_buf: [u8; 16] = unsafe { mem::uninitialized() };
95-
try!(reader.read_exact(&mut local_buf));
95+
use std::mem;
96+
97+
let mut local_buf: [u8; 16] = unsafe { mem::MaybeUninit::uninit().assume_init() };
98+
reader.read_exact(&mut local_buf)?;
9699
let val = unsafe { Decimal128::from_raw_bytes_le(local_buf) };
97100
Ok(val)
98101
}
@@ -232,6 +235,7 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
232235
}
233236
}
234237
Some(Symbol) => read_string(reader, utf8_lossy).map(Bson::Symbol),
238+
#[cfg(feature = "decimal128")]
235239
Some(Decimal128Bit) => read_f128(reader).map(Bson::Decimal128),
236240
Some(Undefined) | Some(DbPointer) | Some(MaxKey) | Some(MinKey) | None => {
237241
Err(DecoderError::UnrecognizedElementType(tag))

src/decoder/serde.rs

+28-24
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,29 @@ use serde::de::{
77
};
88

99
use super::error::{DecoderError, DecoderResult};
10-
use bson::{Bson, TimeStamp, UtcDateTime};
11-
use decimal128::Decimal128;
12-
use oid::ObjectId;
13-
use ordered::{OrderedDocument, OrderedDocumentIntoIterator, OrderedDocumentVisitor};
14-
use spec::BinarySubtype;
10+
use crate::bson::{Bson, TimeStamp, UtcDateTime};
11+
#[cfg(feature = "decimal128")]
12+
use crate::decimal128::Decimal128;
13+
use crate::oid::ObjectId;
14+
use crate::ordered::{OrderedDocument, OrderedDocumentIntoIterator, OrderedDocumentVisitor};
15+
use crate::spec::BinarySubtype;
1516

1617
pub struct BsonVisitor;
1718

1819
impl<'de> Deserialize<'de> for ObjectId {
1920
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2021
where D: Deserializer<'de>
2122
{
22-
deserializer
23-
.deserialize_map(BsonVisitor)
24-
.and_then(|bson| if let Bson::ObjectId(oid) = bson {
25-
Ok(oid)
26-
} else {
27-
let err = format!("expected objectId extended document, found {}", bson);
28-
Err(de::Error::invalid_type(Unexpected::Map, &&err[..]))
29-
})
23+
deserializer.deserialize_map(BsonVisitor).and_then(|bson| {
24+
if let Bson::ObjectId(oid) = bson {
25+
Ok(oid)
26+
} else {
27+
let err =
28+
format!("expected objectId extended document, found {}",
29+
bson);
30+
Err(de::Error::invalid_type(Unexpected::Map, &&err[..]))
31+
}
32+
})
3033
}
3134
}
3235

@@ -254,13 +257,13 @@ impl<'de> Deserializer<'de> for Decoder {
254257
Bson::Array(v) => {
255258
let len = v.len();
256259
visitor.visit_seq(SeqDecoder { iter: v.into_iter(),
257-
len: len, })
260+
len: len })
258261
}
259262
Bson::Document(v) => {
260263
let len = v.len();
261264
visitor.visit_map(MapDecoder { iter: v.into_iter(),
262265
value: None,
263-
len: len, })
266+
len: len })
264267
}
265268
Bson::Boolean(v) => visitor.visit_bool(v),
266269
Bson::Null => visitor.visit_unit(),
@@ -272,7 +275,7 @@ impl<'de> Deserializer<'de> for Decoder {
272275
let len = doc.len();
273276
visitor.visit_map(MapDecoder { iter: doc.into_iter(),
274277
value: None,
275-
len: len, })
278+
len: len })
276279
}
277280
}
278281
}
@@ -300,7 +303,7 @@ impl<'de> Deserializer<'de> for Decoder {
300303
Some(Bson::Document(value)) => value,
301304
Some(Bson::String(variant)) => {
302305
return visitor.visit_enum(EnumDecoder { val: Bson::String(variant),
303-
decoder: VariantDecoder { val: None }, });
306+
decoder: VariantDecoder { val: None } });
304307
}
305308
Some(_) => {
306309
return Err(DecoderError::InvalidType("expected an enum".to_owned()));
@@ -321,7 +324,7 @@ impl<'de> Deserializer<'de> for Decoder {
321324
match iter.next() {
322325
Some(_) => Err(DecoderError::InvalidType("expected a single key:value pair".to_owned())),
323326
None => visitor.visit_enum(EnumDecoder { val: Bson::String(variant),
324-
decoder: VariantDecoder { val: Some(value) }, }),
327+
decoder: VariantDecoder { val: Some(value) } }),
325328
}
326329
}
327330

@@ -332,7 +335,7 @@ impl<'de> Deserializer<'de> for Decoder {
332335
visitor.visit_newtype_struct(self)
333336
}
334337

335-
forward_to_deserialize!{
338+
forward_to_deserialize! {
336339
deserialize_bool();
337340
deserialize_u8();
338341
deserialize_u16();
@@ -404,7 +407,7 @@ impl<'de> VariantAccess<'de> for VariantDecoder {
404407
{
405408
if let Bson::Array(fields) = self.val.take().ok_or(DecoderError::EndOfStream)? {
406409
let de = SeqDecoder { len: fields.len(),
407-
iter: fields.into_iter(), };
410+
iter: fields.into_iter() };
408411
de.deserialize_any(visitor)
409412
} else {
410413
return Err(DecoderError::InvalidType("expected a tuple".to_owned()));
@@ -417,7 +420,7 @@ impl<'de> VariantAccess<'de> for VariantDecoder {
417420
if let Bson::Document(fields) = self.val.take().ok_or(DecoderError::EndOfStream)? {
418421
let de = MapDecoder { len: fields.len(),
419422
iter: fields.into_iter(),
420-
value: None, };
423+
value: None };
421424
de.deserialize_any(visitor)
422425
} else {
423426
return Err(DecoderError::InvalidType("expected a struct".to_owned()));
@@ -444,7 +447,7 @@ impl<'de> Deserializer<'de> for SeqDecoder {
444447
}
445448
}
446449

447-
forward_to_deserialize!{
450+
forward_to_deserialize! {
448451
deserialize_bool();
449452
deserialize_u8();
450453
deserialize_u16();
@@ -551,7 +554,7 @@ impl<'de> Deserializer<'de> for MapDecoder {
551554
visitor.visit_map(self)
552555
}
553556

554-
forward_to_deserialize!{
557+
forward_to_deserialize! {
555558
deserialize_bool();
556559
deserialize_u8();
557560
deserialize_u16();
@@ -592,13 +595,14 @@ impl<'de> Deserialize<'de> for TimeStamp {
592595
let ts = ts.to_le();
593596

594597
Ok(TimeStamp { t: ((ts as u64) >> 32) as u32,
595-
i: (ts & 0xFFFF_FFFF) as u32, })
598+
i: (ts & 0xFFFF_FFFF) as u32 })
596599
}
597600
_ => Err(D::Error::custom("expecting TimeStamp")),
598601
}
599602
}
600603
}
601604

605+
#[cfg(feature = "decimal128")]
602606
impl<'de> Deserialize<'de> for Decimal128 {
603607
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
604608
where D: Deserializer<'de>

0 commit comments

Comments
 (0)