Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

RUST-1592 Support decimal128 to/from human-readable strings #404

Merged
merged 30 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4470237
untested parsing
abr-egn Feb 2, 2023
a10faa3
partial format impl and a passing test
abr-egn Feb 3, 2023
3a63afc
rework parsing
abr-egn Feb 3, 2023
6e22a6d
tidy
abr-egn Feb 3, 2023
00f52b6
another passing test
abr-egn Feb 3, 2023
a2139d9
remove some dynamic alloc
abr-egn Feb 3, 2023
95843b1
remove other dynamic alloc
abr-egn Feb 3, 2023
db7628f
produce human-readable
abr-egn Feb 7, 2023
2e77328
improve parsing readability
abr-egn Feb 8, 2023
0b938ee
further parsing readability
abr-egn Feb 8, 2023
010c89e
packing
abr-egn Feb 8, 2023
326d0aa
roundtrip packing tests and bugfix
abr-egn Feb 8, 2023
b9819cc
untested string parsing
abr-egn Feb 8, 2023
6f85924
some passing tests and a failing one
abr-egn Feb 8, 2023
4033eb0
now passing
abr-egn Feb 8, 2023
78e1bd6
zero invalid coefficients; add more tests
abr-egn Feb 9, 2023
2d6c658
fix a few more bugs
abr-egn Feb 9, 2023
0d73014
hypothetical decimal128 serde support
abr-egn Feb 9, 2023
7fefa3b
extjson support
abr-egn Feb 9, 2023
b3da1e3
running the corpus test, and more fixes
abr-egn Feb 9, 2023
9076e06
passing!
abr-egn Feb 9, 2023
d03efff
format and clippy
abr-egn Feb 9, 2023
6d45502
readability tweaks
abr-egn Feb 9, 2023
6bff163
bump msrv to 1.56
abr-egn Feb 9, 2023
e8e411b
fix serde-tests
abr-egn Feb 9, 2023
82461c0
msrv compile fix
abr-egn Feb 9, 2023
95da098
fix msrv compilation again
abr-egn Feb 9, 2023
869acb8
shift error handling
abr-egn Feb 10, 2023
c4c4cb7
simpler byteorder flipping
abr-egn Feb 10, 2023
fc99b93
review updates
abr-egn Feb 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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