Skip to content

Commit fda2cf3

Browse files
authored
RUST-1592 Support decimal128 to/from human-readable strings (#404)
1 parent 79ab64e commit fda2cf3

File tree

11 files changed

+507
-79
lines changed

11 files changed

+507
-79
lines changed

.evergreen/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ axes:
181181
- id: "extra-rust-versions"
182182
values:
183183
- id: "min"
184-
display_name: "1.53 (minimum supported version)"
184+
display_name: "1.56 (minimum supported version)"
185185
variables:
186-
RUST_VERSION: "1.53.0"
186+
RUST_VERSION: "1.56.0"
187187
MSRV: "true"
188188
- id: "nightly"
189189
display_name: "nightly"

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ uuid = { version = "1.1.2", features = ["serde", "v4"] }
6767
serde_bytes = "0.11.5"
6868
serde_with = { version = "1", optional = true }
6969
time = { version = "0.3.9", features = ["formatting", "parsing", "macros", "large-dates"] }
70+
bitvec = "1.0.1"
7071

7172
[dev-dependencies]
7273
assert_matches = "1.2"
@@ -78,4 +79,4 @@ chrono = { version = "0.4", features = ["serde", "clock", "std"], default-featur
7879

7980
[package.metadata.docs.rs]
8081
all-features = true
81-
rustdoc-args = ["--cfg", "docsrs"]
82+
rustdoc-args = ["--cfg", "docsrs"]

serde-tests/json.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn all_types_json() {
4848
"undefined": { "$undefined": true },
4949
"code": { "$code": code },
5050
"code_w_scope": { "$code": code_w_scope.code, "$scope": scope_json },
51-
"decimal": { "$numberDecimalBytes": v.decimal.bytes() },
51+
"decimal": { "$numberDecimal": v.decimal.to_string() },
5252
"symbol": { "$symbol": "ok" },
5353
"min_key": { "$minKey": 1 },
5454
"max_key": { "$maxKey": 1 },

src/bson.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ impl Bson {
455455
"$date": { "$numberLong": v.timestamp_millis().to_string() },
456456
}),
457457
Bson::Symbol(v) => json!({ "$symbol": v }),
458-
Bson::Decimal128(_) => panic!("Decimal128 extended JSON not implemented yet."),
458+
Bson::Decimal128(v) => json!({ "$numberDecimal": v.to_string() }),
459459
Bson::Undefined => json!({ "$undefined": true }),
460460
Bson::MinKey => json!({ "$minKey": 1 }),
461461
Bson::MaxKey => json!({ "$maxKey": 1 }),
@@ -474,9 +474,6 @@ impl Bson {
474474
}
475475

476476
/// Converts the Bson value into its [canonical extended JSON representation](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/).
477-
///
478-
/// Note: extended json encoding for `Decimal128` values is not supported. If this method is
479-
/// called on a case which contains a `Decimal128` value, it will panic.
480477
pub fn into_canonical_extjson(self) -> Value {
481478
match self {
482479
Bson::Int32(i) => json!({ "$numberInt": i.to_string() }),
@@ -705,6 +702,14 @@ impl Bson {
705702
_ => {}
706703
},
707704

705+
["$numberDecimal"] => {
706+
if let Ok(d) = doc.get_str("$numberDecimal") {
707+
if let Ok(d) = d.parse() {
708+
return Bson::Decimal128(d);
709+
}
710+
}
711+
}
712+
708713
["$numberDecimalBytes"] => {
709714
if let Ok(bytes) = doc.get_binary_generic("$numberDecimalBytes") {
710715
if let Ok(b) = bytes.clone().try_into() {

src/de/serde.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -466,10 +466,15 @@ impl<'de> Visitor<'de> for BsonVisitor {
466466
}
467467

468468
"$numberDecimal" => {
469-
return Err(Error::custom(
470-
"deserializing decimal128 values from strings is not currently supported"
471-
.to_string(),
472-
));
469+
let string: String = visitor.next_value()?;
470+
return Ok(Bson::Decimal128(string.parse::<Decimal128>().map_err(
471+
|_| {
472+
V::Error::invalid_value(
473+
Unexpected::Str(&string),
474+
&"decimal128 as a string",
475+
)
476+
},
477+
)?));
473478
}
474479

475480
"$numberDecimalBytes" => {

0 commit comments

Comments
 (0)