diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 8fe823de..d3cfe0f9 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -92,16 +92,6 @@ functions: ${PREPARE_SHELL} .evergreen/run-tests-u2i.sh - "run decimal128 tests": - - command: shell.exec - type: test - params: - shell: bash - working_dir: "src" - script: | - ${PREPARE_SHELL} - .evergreen/run-tests-decimal128.sh - "compile only": - command: shell.exec type: test @@ -160,10 +150,6 @@ tasks: commands: - func: "run u2i tests" - - name: "test-decimal128" - commands: - - func: "run decimal128 tests" - - name: "compile-only" commands: - func: "compile only" @@ -197,7 +183,6 @@ buildvariants: tasks: - name: "test" - name: "test-u2i" - - name: "test-decimal128" - matrix_name: "compile only" matrix_spec: diff --git a/.evergreen/run-tests-decimal128.sh b/.evergreen/run-tests-decimal128.sh deleted file mode 100755 index 51f62cbf..00000000 --- a/.evergreen/run-tests-decimal128.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -set -o errexit - -. ~/.cargo/env -RUST_BACKTRACE=1 cargo test --features decimal128 - -cd serde-tests -RUST_BACKTRACE=1 cargo test --features decimal128 diff --git a/.evergreen/run-tests-serde.sh b/.evergreen/run-tests-serde.sh deleted file mode 100755 index d95aa543..00000000 --- a/.evergreen/run-tests-serde.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -set -o errexit - -. ~/.cargo/env -cd serde-tests -RUST_BACKTRACE=1 cargo test diff --git a/Cargo.toml b/Cargo.toml index 25a6a02b..1623255d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,8 +39,6 @@ chrono-0_4 = [] uuid-0_8 = [] # attempt to encode unsigned types in signed types u2i = [] -# Decimal128 in BSON 1.1 -decimal128 = ["decimal"] [lib] name = "bson" @@ -53,7 +51,6 @@ serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["preserve_order"] } indexmap = "1.6.2" hex = "0.4.2" -decimal = { version = "2.1.0", default_features = false, optional = true } base64 = "0.13.0" lazy_static = "1.4.0" uuid = "0.8.1" @@ -64,6 +61,3 @@ assert_matches = "1.2" serde_bytes = "0.11" pretty_assertions = "0.6.1" chrono = { version = "0.4", features = ["serde"] } - -[package.metadata.docs.rs] -features = ["decimal128"] diff --git a/serde-tests/Cargo.toml b/serde-tests/Cargo.toml index 45bdfce3..78ef47d7 100644 --- a/serde-tests/Cargo.toml +++ b/serde-tests/Cargo.toml @@ -6,7 +6,6 @@ edition = "2018" [features] u2i = ["bson/u2i"] -decimal128 = ["bson/decimal128"] [dependencies] bson = { path = ".." } diff --git a/serde-tests/test.rs b/serde-tests/test.rs index 6e46dddd..b14ae74a 100644 --- a/serde-tests/test.rs +++ b/serde-tests/test.rs @@ -14,8 +14,6 @@ use std::{ collections::{BTreeMap, HashSet}, }; -#[cfg(feature = "decimal128")] -use bson::Decimal128; use bson::{ doc, oid::ObjectId, @@ -749,16 +747,12 @@ fn all_types() { let oid = ObjectId::new(); let subdoc = doc! { "k": true, "b": { "hello": "world" } }; - #[cfg(not(feature = "decimal128"))] let decimal = { let bytes = hex::decode("18000000136400D0070000000000000000000000003A3000").unwrap(); let d = Document::from_reader(bytes.as_slice()).unwrap(); d.get("d").unwrap().clone() }; - #[cfg(feature = "decimal128")] - let decimal = Bson::Decimal128(Decimal128::from_str("2.000")); - let doc = doc! { "x": 1, "y": 2_i64, @@ -902,7 +896,7 @@ fn u2i() { "u_32": 1234_i64, "u_32_max": u32::MAX as i64, "u_64": 12345_i64, - "i_64_max": i64::MAX as u64, + "i_64_max": i64::MAX, }; run_test(&v, &expected, "u2i - valid"); diff --git a/src/bson.rs b/src/bson.rs index cadbd074..6d78809a 100644 --- a/src/bson.rs +++ b/src/bson.rs @@ -361,9 +361,7 @@ impl From for Value { impl Bson { /// Converts the Bson value into its [relaxed extended JSON representation](https://docs.mongodb.com/manual/reference/mongodb-extended-json/). /// - /// Note: extended json encoding for `Decimal128` values is not supported without the - /// "decimal128" feature flag. If this method is called on a case which contains a - /// `Decimal128` value, it will panic. + /// Note: If this method is called on a case which contains a `Decimal128` value, it will panic. pub fn into_relaxed_extjson(self) -> Value { match self { Bson::Double(v) if v.is_nan() => { @@ -433,13 +431,7 @@ impl Bson { "$date": { "$numberLong": v.timestamp_millis().to_string() }, }), Bson::Symbol(v) => json!({ "$symbol": v }), - #[cfg(feature = "decimal128")] - Bson::Decimal128(ref v) => json!({ "$numberDecimal": v.to_string() }), - #[cfg(not(feature = "decimal128"))] - Bson::Decimal128(_) => panic!( - "Decimal128 extended JSON not implemented yet. Use the decimal128 feature to \ - enable experimental support for it." - ), + Bson::Decimal128(_) => panic!("Decimal128 extended JSON not implemented yet."), Bson::Undefined => json!({ "$undefined": true }), Bson::MinKey => json!({ "$minKey": 1 }), Bson::MaxKey => json!({ "$maxKey": 1 }), @@ -459,9 +451,8 @@ impl Bson { /// Converts the Bson value into its [canonical extended JSON representation](https://docs.mongodb.com/manual/reference/mongodb-extended-json/). /// - /// Note: extended json encoding for `Decimal128` values is not supported without the - /// "decimal128" feature flag. If this method is called on a case which contains a - /// `Decimal128` value, it will panic. + /// Note: extended json encoding for `Decimal128` values is not supported. If this method is + /// called on a case which contains a `Decimal128` value, it will panic. pub fn into_canonical_extjson(self) -> Value { match self { Bson::Int32(i) => json!({ "$numberInt": i.to_string() }), @@ -594,12 +585,6 @@ impl Bson { "$symbol": v.to_owned(), } } - #[cfg(feature = "decimal128")] - Bson::Decimal128(ref v) => { - doc! { - "$numberDecimal": (v.to_string()) - } - } Bson::Undefined => { doc! { "$undefined": true, @@ -683,25 +668,10 @@ impl Bson { _ => {} }, - #[cfg(feature = "decimal128")] - ["$numberDecimal"] => { - if let Ok(d) = doc.get_str("$numberDecimal") { - if let Ok(d) = d.parse() { - return Bson::Decimal128(d); - } - } - } - ["$numberDecimalBytes"] => { if let Ok(bytes) = doc.get_binary_generic("$numberDecimalBytes") { if let Ok(b) = bytes.clone().try_into() { - #[cfg(not(feature = "decimal128"))] return Bson::Decimal128(Decimal128 { bytes: b }); - - #[cfg(feature = "decimal128")] - unsafe { - return Bson::Decimal128(Decimal128::from_raw_bytes_le(b)); - } } } } diff --git a/src/de/mod.rs b/src/de/mod.rs index 8a288f00..fccfcef7 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -162,7 +162,6 @@ fn read_f64(reader: &mut R) -> Result { /// Placeholder decoder for `Decimal128`. Reads 128 bits and just stores them, does no validation or /// parsing. -#[cfg(not(feature = "decimal128"))] #[inline] fn read_f128(reader: &mut R) -> Result { let mut buf = [0u8; 128 / 8]; @@ -170,15 +169,6 @@ fn read_f128(reader: &mut R) -> Result { Ok(Decimal128 { bytes: buf }) } -#[cfg(feature = "decimal128")] -#[inline] -fn read_f128(reader: &mut R) -> Result { - let mut local_buf = [0u8; 16]; - reader.read_exact(&mut local_buf)?; - let val = unsafe { Decimal128::from_raw_bytes_le(local_buf) }; - Ok(val) -} - fn deserialize_array(reader: &mut R, utf8_lossy: bool) -> Result { let mut arr = Array::new(); let length = read_i32(reader)?; diff --git a/src/de/raw.rs b/src/de/raw.rs index 261b9e73..4ac73afb 100644 --- a/src/de/raw.rs +++ b/src/de/raw.rs @@ -581,15 +581,7 @@ impl<'de> serde::de::Deserializer<'de> for Decimal128Deserializer { where V: serde::de::Visitor<'de>, { - #[cfg(not(feature = "decimal128"))] - { - visitor.visit_bytes(&self.0.bytes) - } - - #[cfg(feature = "decimal128")] - { - visitor.visit_bytes(&self.0.to_raw_bytes_le()) - } + visitor.visit_bytes(&self.0.bytes) } serde::forward_to_deserialize_any! { diff --git a/src/de/serde.rs b/src/de/serde.rs index 7831a900..bd74dd99 100644 --- a/src/de/serde.rs +++ b/src/de/serde.rs @@ -378,21 +378,10 @@ impl<'de> Visitor<'de> for BsonVisitor { } "$numberDecimal" => { - #[cfg(not(feature = "decimal128"))] - { - return Err(Error::custom(format!( - "enable the experimental decimal128 feature flag to deserialize \ - decimal128 from string" - ))); - } - - #[cfg(feature = "decimal128")] - { - let s = visitor.next_value::()?; - return Ok(Bson::Decimal128(s.parse().map_err(|_| { - Error::custom(format!("malformatted decimal128 string: {}", s)) - })?)); - } + return Err(Error::custom( + "deserializing decimal128 values from strings is not currently supported" + .to_string(), + )); } "$numberDecimalBytes" => { @@ -403,17 +392,7 @@ impl<'de> Visitor<'de> for BsonVisitor { v.len() )) })?; - #[cfg(not(feature = "decimal128"))] - { - return Ok(Bson::Decimal128(Decimal128 { bytes: arr })); - } - - #[cfg(feature = "decimal128")] - { - unsafe { - return Ok(Bson::Decimal128(Decimal128::from_raw_bytes_le(arr))); - } - } + return Ok(Bson::Decimal128(Decimal128 { bytes: arr })); } _ => { @@ -982,7 +961,6 @@ impl<'de> Deserialize<'de> for Binary { } } -#[cfg(feature = "decimal128")] impl<'de> Deserialize<'de> for Decimal128 { fn deserialize(deserializer: D) -> Result where diff --git a/src/decimal128.rs b/src/decimal128.rs index 7660087c..e4f343c0 100644 --- a/src/decimal128.rs +++ b/src/decimal128.rs @@ -1,294 +1,37 @@ //! [BSON Decimal128](https://github.com/mongodb/specifications/blob/master/source/bson-decimal128/decimal128.rst) data type representation -#[cfg(feature = "decimal128")] -use decimal::d128; use std::fmt; -/// Decimal128 type. +/// Struct representing a BSON Decimal128 type. /// -/// Currently, this type does not have any functionality and can only be serialized and -/// deserialized from existing documents that contain BSON decimal128s. -/// -/// Experimental functionality can be enabled through the usage of the `"decimal128"` -/// feature flag. Note that the API and behavior of such functionality are unstable and -/// subject to change. -#[derive(Clone, PartialEq, PartialOrd)] +/// Currently, this type can only be used to round-trip through BSON. See +/// [RUST-36](https://jira.mongodb.org/browse/RUST-36) to track the progress towards a complete implementation. +#[derive(Clone, PartialEq)] pub struct Decimal128 { - #[cfg(not(feature = "decimal128"))] /// BSON bytes containing the decimal128. Stored for round tripping. pub(crate) bytes: [u8; 128 / 8], - - #[cfg(feature = "decimal128")] - inner: decimal::d128, } -#[cfg(feature = "decimal128")] impl Decimal128 { - /// Construct a `Decimal128` from string. - /// - /// For example: - /// - /// * `NaN` - /// * `Infinity` or `Inf` - /// * `1.0`, `+37.0`, `0.73e-7`, `.5` - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let dec128 = Decimal128::from_str("1.05E+3"); - /// ``` - #[allow(clippy::should_implement_trait)] - pub fn from_str(s: &str) -> Decimal128 { - Decimal128 { - inner: s.parse::().expect("Invalid Decimal128 string"), - } - } - - /// Construct a `Decimal128` from a `i32` number. - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let num: i32 = 23; - /// let dec128 = Decimal128::from_i32(num); - /// ``` - pub fn from_i32(d: i32) -> Decimal128 { - Decimal128 { - inner: From::from(d), - } - } - - /// Construct a `Decimal128` from a `u32` number. - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let num: u32 = 78; - /// let dec128 = Decimal128::from_u32(num); - /// ``` - pub fn from_u32(d: u32) -> Decimal128 { - Decimal128 { - inner: From::from(d), - } - } - - /// Construct a `Decimal128` from a `i32` number. - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let num: i32 = 23; - /// let dec128 = Decimal128::from_i32(num); - /// let int = dec128.to_i32(); - /// assert_eq!(int, num); - /// ``` - pub fn to_i32(&self) -> i32 { - Into::into(self.inner) - } - - /// Construct a `Decimal128` from a `i32` number. - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let num: u32 = 23; - /// let dec128 = Decimal128::from_u32(num); - /// let int = dec128.to_u32(); - /// assert_eq!(int, num); - /// ``` - pub fn to_u32(&self) -> u32 { - Into::into(self.inner) - } - - /// Create a new Decimal128 as `0`. - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let dec128 = Decimal128::zero(); - /// ``` - pub fn zero() -> Decimal128 { - Decimal128 { - inner: d128::zero(), - } - } - - #[doc(hidden)] - pub unsafe fn from_raw_bytes_le(mut raw: [u8; 16]) -> Decimal128 { - if cfg!(target_endian = "big") { - raw.reverse(); - } - - Decimal128 { - inner: d128::from_raw_bytes(raw), - } - } - - #[doc(hidden)] - pub fn to_raw_bytes_le(&self) -> [u8; 16] { - let mut buf = self.inner.to_raw_bytes(); - if cfg!(target_endian = "big") { - buf.reverse(); - } - buf - } - - /// Check if value is `NaN` - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let num: u32 = 78; - /// let dec128 = Decimal128::from_u32(num); - /// assert!(!dec128.is_nan()); - /// ``` - pub fn is_nan(&self) -> bool { - self.inner.is_nan() + /// Constructs a new `Decimal128` from the provided raw byte representation. + pub fn from_bytes(bytes: [u8; 128 / 8]) -> Self { + Self { bytes } } - /// Check if value is 0 - /// - /// ```rust - /// use bson::decimal128::Decimal128; - /// - /// let num: u32 = 0; - /// let dec128 = Decimal128::from_u32(num); - /// assert!(dec128.is_zero()); - /// ``` - pub fn is_zero(&self) -> bool { - self.inner.is_zero() + /// Returns the raw byte representation of this `Decimal128`. + pub fn bytes(&self) -> [u8; 128 / 8] { + self.bytes } } impl fmt::Debug for Decimal128 { - #[cfg(feature = "decimal128")] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Decimal128(\"{:?}\")", self.inner) - } - - #[cfg(not(feature = "decimal128"))] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Decimal128(...)") } } impl fmt::Display for Decimal128 { - #[cfg(feature = "decimal128")] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.inner) - } - - #[cfg(not(feature = "decimal128"))] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) } } - -#[cfg(feature = "decimal128")] -impl fmt::LowerHex for Decimal128 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::fmt(&self.inner, f) - } -} - -#[cfg(feature = "decimal128")] -impl fmt::LowerExp for Decimal128 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::fmt(&self.inner, f) - } -} - -#[cfg(feature = "decimal128")] -impl std::str::FromStr for Decimal128 { - type Err = (); - fn from_str(s: &str) -> Result { - Ok(Decimal128::from_str(s)) - } -} - -#[cfg(feature = "decimal128")] -impl From for d128 { - fn from(decimal: Decimal128) -> d128 { - decimal.inner - } -} - -#[cfg(feature = "decimal128")] -impl From for Decimal128 { - fn from(d: d128) -> Decimal128 { - Decimal128 { inner: d } - } -} - -#[cfg(feature = "decimal128")] -impl Default for Decimal128 { - fn default() -> Decimal128 { - Decimal128::zero() - } -} - -#[cfg(test)] -#[cfg(feature = "decimal128")] -mod test { - use super::*; - - #[test] - fn decimal128_string() { - assert!(Decimal128::from_str("0").is_zero()); - assert!(!Decimal128::from_str("12").is_nan()); - assert!(!Decimal128::from_str("-76").is_nan()); - assert!(!Decimal128::from_str("12.70").is_nan()); - assert!(!Decimal128::from_str("+0.003").is_nan()); - assert!(!Decimal128::from_str("017.").is_nan()); - assert!(!Decimal128::from_str(".5").is_nan()); - assert!(!Decimal128::from_str("4E+9").is_nan()); - assert!(!Decimal128::from_str("0.73e-7").is_nan()); - assert!(!Decimal128::from_str("Inf").is_nan()); - assert!(!Decimal128::from_str("-infinity").is_nan()); - assert!(Decimal128::from_str("NaN").is_nan()); - } - - #[test] - fn decimal128_i32() { - let num: i32 = 89; - let dec128 = Decimal128::from_i32(num); - - assert!(!dec128.is_nan()); - assert!(!dec128.is_zero()); - assert_eq!(dec128.to_i32(), num); - } - - #[test] - fn decimal128_u32() { - let num: u32 = 89; - let dec128 = Decimal128::from_u32(num); - - assert!(!dec128.is_nan()); - assert!(!dec128.is_zero()); - assert_eq!(dec128.to_u32(), num); - } - - #[test] - fn decimal128_0() { - let dec128 = Decimal128::zero(); - assert!(dec128.is_zero()); - } - - #[test] - fn decimal128_is_zero() { - let dec128 = Decimal128::from_i32(234); - assert!(!dec128.is_zero()); - - let dec128_0 = Decimal128::from_i32(0); - assert!(dec128_0.is_zero()); - } - - #[test] - fn decimal128_is_nan() { - let dec128 = Decimal128::from_str("NaN"); - assert!(dec128.is_nan()); - - let dec128 = Decimal128::from_i32(234); - assert!(!dec128.is_nan()); - } -} diff --git a/src/document.rs b/src/document.rs index f9e1b692..d2cb1e0f 100644 --- a/src/document.rs +++ b/src/document.rs @@ -12,14 +12,13 @@ use ahash::RandomState; use indexmap::IndexMap; use serde::de::Error; -#[cfg(feature = "decimal128")] -use crate::decimal128::Decimal128; use crate::{ bson::{Array, Binary, Bson, Timestamp}, de::{deserialize_bson_kvp, ensure_read_exactly, read_i32, MIN_BSON_DOCUMENT_SIZE}, oid::ObjectId, ser::{serialize_bson, write_i32}, spec::BinarySubtype, + Decimal128, }; /// Error to indicate that either a value was empty or it contained an unexpected @@ -231,7 +230,6 @@ impl Document { } /// Get a reference to a Decimal128 value for key, if it exists. - #[cfg(feature = "decimal128")] pub fn get_decimal128(&self, key: impl AsRef) -> ValueAccessResult<&Decimal128> { match self.get(key) { Some(&Bson::Decimal128(ref v)) => Ok(v), @@ -241,7 +239,6 @@ impl Document { } /// Get a mutable reference to a Decimal128 value for key, if it exists. - #[cfg(feature = "decimal128")] pub fn get_decimal128_mut( &mut self, key: impl AsRef, diff --git a/src/extjson/de.rs b/src/extjson/de.rs index 0d12857e..b5c3eea4 100644 --- a/src/extjson/de.rs +++ b/src/extjson/de.rs @@ -160,16 +160,7 @@ impl TryFrom> for Bson { } if obj.contains_key("$numberDecimal") { - #[cfg(feature = "decimal128")] - { - let decimal: models::Decimal128 = serde_json::from_value(obj.into())?; - return Ok(Bson::Decimal128(decimal.parse()?)); - } - - #[cfg(not(feature = "decimal128"))] - { - return Err(Error::custom("decimal128 extjson support not implemented")); - } + return Err(Error::custom("decimal128 extjson support not implemented")); } if obj.contains_key("$undefined") { diff --git a/src/extjson/models.rs b/src/extjson/models.rs index 79065c19..41851f21 100644 --- a/src/extjson/models.rs +++ b/src/extjson/models.rs @@ -344,27 +344,6 @@ impl DbPointer { } } -#[cfg(feature = "decimal128")] -#[derive(Deserialize)] -#[serde(deny_unknown_fields)] -pub(crate) struct Decimal128 { - #[serde(rename = "$numberDecimal")] - value: String, -} - -#[cfg(feature = "decimal128")] -impl Decimal128 { - pub(crate) fn parse(self) -> extjson::de::Result { - let decimal128: crate::Decimal128 = self.value.parse().map_err(|_| { - extjson::de::Error::invalid_value( - Unexpected::Str(self.value.as_str()), - &"decimal128 value as a string", - ) - })?; - Ok(decimal128) - } -} - #[derive(Deserialize)] #[serde(deny_unknown_fields)] pub(crate) struct Undefined { diff --git a/src/ser/mod.rs b/src/ser/mod.rs index f18dd155..9e3c3ab1 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -32,8 +32,6 @@ pub use self::{ use std::{io::Write, iter::FromIterator, mem}; -#[cfg(feature = "decimal128")] -use crate::decimal128::Decimal128; use crate::{ bson::{Binary, Bson, DbPointer, Document, JavaScriptCodeWithScope, Regex}, de::MAX_BSON_SIZE, @@ -78,13 +76,6 @@ fn write_f64(writer: &mut W, val: f64) -> Result<()> { .map_err(From::from) } -#[cfg(feature = "decimal128")] -#[inline] -fn write_f128(writer: &mut W, val: Decimal128) -> Result<()> { - let raw = val.to_raw_bytes_le(); - writer.write_all(&raw).map_err(From::from) -} - #[inline] fn write_binary(mut writer: W, bytes: &[u8], subtype: BinarySubtype) -> Result<()> { let len = if let BinarySubtype::BinaryOld = subtype { @@ -172,13 +163,10 @@ pub(crate) fn serialize_bson( Bson::DateTime(ref v) => write_i64(writer, v.timestamp_millis()), Bson::Null => Ok(()), Bson::Symbol(ref v) => write_string(writer, v), - #[cfg(not(feature = "decimal128"))] Bson::Decimal128(ref v) => { writer.write_all(&v.bytes)?; Ok(()) } - #[cfg(feature = "decimal128")] - Bson::Decimal128(ref v) => write_f128(writer, v.clone()), Bson::Undefined => Ok(()), Bson::MinKey => Ok(()), Bson::MaxKey => Ok(()), diff --git a/src/ser/raw/value_serializer.rs b/src/ser/raw/value_serializer.rs index ace276b1..9af76549 100644 --- a/src/ser/raw/value_serializer.rs +++ b/src/ser/raw/value_serializer.rs @@ -5,8 +5,6 @@ use serde::{ Serialize, }; -#[cfg(feature = "decimal128")] -use crate::Decimal128; use crate::{ oid::ObjectId, ser::{write_binary, write_cstring, write_i32, write_i64, write_string, Error, Result}, @@ -258,11 +256,6 @@ impl<'a, 'b> serde::Serializer for &'b mut ValueSerializer<'a> { code: v.to_string(), }; } - #[cfg(feature = "decimal128")] - SerializationStep::Decimal128Value => { - let d = Decimal128::from_str(v); - self.root_serializer.bytes.write_all(&d.to_raw_bytes_le())?; - } s => { return Err(Error::custom(format!( "can't serialize string for step {:?}", diff --git a/src/ser/serde.rs b/src/ser/serde.rs index 04f61ba0..277a5db6 100644 --- a/src/ser/serde.rs +++ b/src/ser/serde.rs @@ -9,17 +9,15 @@ use serde::ser::{ SerializeTupleStruct, SerializeTupleVariant, }; -#[cfg(not(feature = "decimal128"))] use serde_bytes::Bytes; -#[cfg(feature = "decimal128")] -use crate::decimal128::Decimal128; use crate::{ bson::{Array, Binary, Bson, DbPointer, Document, JavaScriptCodeWithScope, Regex, Timestamp}, datetime::DateTime, extjson, oid::ObjectId, spec::BinarySubtype, + Decimal128, }; use super::{to_bson, Error}; @@ -82,14 +80,11 @@ impl Serialize for Bson { } Bson::RegularExpression(re) => re.serialize(serializer), Bson::Timestamp(t) => t.serialize(serializer), - #[cfg(not(feature = "decimal128"))] Bson::Decimal128(d) => { let mut state = serializer.serialize_struct("$numberDecimal", 1)?; state.serialize_field("$numberDecimalBytes", Bytes::new(&d.bytes))?; state.end() } - #[cfg(feature = "decimal128")] - Bson::Decimal128(d) => d.serialize(serializer), Bson::Undefined => { let mut state = serializer.serialize_struct("$undefined", 1)?; state.serialize_field("$undefined", &true)?; @@ -600,7 +595,6 @@ impl Serialize for Binary { } } -#[cfg(feature = "decimal128")] impl Serialize for Decimal128 { #[inline] fn serialize(&self, serializer: S) -> Result @@ -608,10 +602,7 @@ impl Serialize for Decimal128 { S: ser::Serializer, { let mut state = serializer.serialize_struct("$numberDecimal", 1)?; - state.serialize_field( - "$numberDecimalBytes", - serde_bytes::Bytes::new(&self.to_raw_bytes_le()), - )?; + state.serialize_field("$numberDecimalBytes", serde_bytes::Bytes::new(&self.bytes))?; state.end() } } diff --git a/src/tests/modules/document.rs b/src/tests/modules/document.rs index 52f61872..6c7669a1 100644 --- a/src/tests/modules/document.rs +++ b/src/tests/modules/document.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "decimal128")] -use crate::decimal128::Decimal128; use crate::{ doc, document::ValueAccessError, @@ -49,15 +47,6 @@ fn ordered_insert_shorthand() { assert_eq!(expected_keys, keys); } -#[cfg(feature = "decimal128")] -fn test_decimal128(doc: &mut Document) { - let _guard = LOCK.run_concurrently(); - let dec = Decimal128::from_str("968E+1"); - doc.insert("decimal128".to_string(), Bson::Decimal128(dec.clone())); - assert_eq!(Some(&Bson::Decimal128(dec.clone())), doc.get("decimal128")); - assert_eq!(Ok(&dec), doc.get_decimal128("decimal128")); -} - #[test] fn test_getters() { let _guard = LOCK.run_concurrently(); @@ -140,9 +129,6 @@ fn test_getters() { assert_eq!(Some(&Bson::DateTime(dt)), doc.get("datetime")); assert_eq!(Ok(&dt), doc.get_datetime("datetime")); - #[cfg(feature = "decimal128")] - test_decimal128(&mut doc); - let object_id = ObjectId::new(); doc.insert("_id".to_string(), Bson::ObjectId(object_id)); assert_eq!(Some(&Bson::ObjectId(object_id)), doc.get("_id")); diff --git a/src/tests/modules/ser.rs b/src/tests/modules/ser.rs index 7e1dbedc..a3185dff 100644 --- a/src/tests/modules/ser.rs +++ b/src/tests/modules/ser.rs @@ -2,8 +2,6 @@ use std::{collections::BTreeMap, u16, u32, u64, u8}; use assert_matches::assert_matches; -#[cfg(feature = "decimal128")] -use crate::decimal128::Decimal128; use crate::{from_bson, oid::ObjectId, ser, tests::LOCK, to_bson, Bson}; #[test] @@ -68,19 +66,6 @@ fn int32() { assert_eq!(deser, obj); } -#[cfg(feature = "decimal128")] -#[test] -fn dec128() { - let _guard = LOCK.run_concurrently(); - let d128 = Decimal128::from_str("1.05E+3"); - let obj = Bson::Decimal128(d128.clone()); - let ser: Decimal128 = from_bson(obj.clone()).unwrap(); - assert_eq!(ser, d128); - - let deser: Bson = to_bson(&ser).unwrap(); - assert_eq!(deser, obj); -} - #[test] #[cfg(not(feature = "u2i"))] fn uint8() { diff --git a/src/tests/modules/serializer_deserializer.rs b/src/tests/modules/serializer_deserializer.rs index f2d5e7f8..cc5f222c 100644 --- a/src/tests/modules/serializer_deserializer.rs +++ b/src/tests/modules/serializer_deserializer.rs @@ -5,8 +5,6 @@ use std::{ use serde::{Deserialize, Serialize}; -#[cfg(feature = "decimal128")] -use crate::decimal128::Decimal128; use crate::{ de::from_document, doc, @@ -17,6 +15,7 @@ use crate::{ to_document, Binary, Bson, + Decimal128, Document, JavaScriptCodeWithScope, Regex, @@ -389,11 +388,12 @@ fn test_deserialize_multiply_overflows_issue64() { assert!(Document::from_reader(&mut Cursor::new(&buffer[..])).is_err()); } -#[cfg(feature = "decimal128")] #[test] fn test_serialize_deserialize_decimal128() { let _guard = LOCK.run_concurrently(); - let val = Bson::Decimal128(Decimal128::from_i32(0)); + let val = Bson::Decimal128(Decimal128 { + bytes: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34], + }); let dst = vec![ 26, 0, 0, 0, 19, 107, 101, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34, 0, ]; diff --git a/src/tests/spec/corpus.rs b/src/tests/spec/corpus.rs index 4623f5dc..9a6b2037 100644 --- a/src/tests/spec/corpus.rs +++ b/src/tests/spec/corpus.rs @@ -195,8 +195,8 @@ fn run_test(test: TestFile) { } // TODO RUST-36: Enable decimal128 tests. - // extJSON not implemented for decimal128 without the feature flag, so we must stop here. - if test.bson_type == "0x13" && !cfg!(feature = "decimal128") { + // extJSON not implemented for decimal128, so we must stop here. + if test.bson_type == "0x13" { continue; } @@ -384,7 +384,7 @@ fn run_test(test: TestFile) { } // TODO RUST-36: Enable decimal128 tests. - if !cfg!(feature = "decimal128") && parse_error.description.contains("$numberDecimal") { + if parse_error.description.contains("$numberDecimal") { continue; }