Skip to content

Commit

Permalink
RUST-1592 Support decimal128 to/from human-readable strings (crosster…
Browse files Browse the repository at this point in the history
  • Loading branch information
abr-egn authored Feb 15, 2023
1 parent 79ab64e commit fda2cf3
Show file tree
Hide file tree
Showing 11 changed files with 507 additions and 79 deletions.
4 changes: 2 additions & 2 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ axes:
- id: "extra-rust-versions"
values:
- id: "min"
display_name: "1.53 (minimum supported version)"
display_name: "1.56 (minimum supported version)"
variables:
RUST_VERSION: "1.53.0"
RUST_VERSION: "1.56.0"
MSRV: "true"
- id: "nightly"
display_name: "nightly"
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ uuid = { version = "1.1.2", features = ["serde", "v4"] }
serde_bytes = "0.11.5"
serde_with = { version = "1", optional = true }
time = { version = "0.3.9", features = ["formatting", "parsing", "macros", "large-dates"] }
bitvec = "1.0.1"

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

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
2 changes: 1 addition & 1 deletion serde-tests/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn all_types_json() {
"undefined": { "$undefined": true },
"code": { "$code": code },
"code_w_scope": { "$code": code_w_scope.code, "$scope": scope_json },
"decimal": { "$numberDecimalBytes": v.decimal.bytes() },
"decimal": { "$numberDecimal": v.decimal.to_string() },
"symbol": { "$symbol": "ok" },
"min_key": { "$minKey": 1 },
"max_key": { "$maxKey": 1 },
Expand Down
13 changes: 9 additions & 4 deletions src/bson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ impl Bson {
"$date": { "$numberLong": v.timestamp_millis().to_string() },
}),
Bson::Symbol(v) => json!({ "$symbol": v }),
Bson::Decimal128(_) => panic!("Decimal128 extended JSON not implemented yet."),
Bson::Decimal128(v) => json!({ "$numberDecimal": v.to_string() }),
Bson::Undefined => json!({ "$undefined": true }),
Bson::MinKey => json!({ "$minKey": 1 }),
Bson::MaxKey => json!({ "$maxKey": 1 }),
Expand All @@ -474,9 +474,6 @@ impl Bson {
}

/// Converts the Bson value into its [canonical extended JSON representation](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/).
///
/// 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() }),
Expand Down Expand Up @@ -705,6 +702,14 @@ impl Bson {
_ => {}
},

["$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() {
Expand Down
13 changes: 9 additions & 4 deletions src/de/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,15 @@ impl<'de> Visitor<'de> for BsonVisitor {
}

"$numberDecimal" => {
return Err(Error::custom(
"deserializing decimal128 values from strings is not currently supported"
.to_string(),
));
let string: String = visitor.next_value()?;
return Ok(Bson::Decimal128(string.parse::<Decimal128>().map_err(
|_| {
V::Error::invalid_value(
Unexpected::Str(&string),
&"decimal128 as a string",
)
},
)?));
}

"$numberDecimalBytes" => {
Expand Down
Loading

0 comments on commit fda2cf3

Please sign in to comment.