зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1773399 - Update rust_decimal to 1.25.0. r=emilio,supply-chain-reviewers,bholley
Differential Revision: https://phabricator.services.mozilla.com/D149327
This commit is contained in:
Родитель
644033c9d8
Коммит
600d66cac5
|
@ -4584,9 +4584,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust_decimal"
|
||||
version = "1.24.0"
|
||||
version = "1.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2ee7337df68898256ad0d4af4aad178210d9e44d2ff900ce44064a97cd86530"
|
||||
checksum = "34a3bb58e85333f1ab191bf979104b586ebd77475bc6681882825f4532dfe87c"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"num-traits",
|
||||
|
|
|
@ -57,6 +57,11 @@ criteria = "safe-to-deploy"
|
|||
version = "0.5.4"
|
||||
notes = "I own this crate (I am contain-rs) and 0.5.4 passes miri. This code is very old and used by lots of people, so I'm pretty confident in it, even though it's in maintenance-mode and missing some nice-to-have APIs."
|
||||
|
||||
[[audits.rust_decimal]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "1.24.0 -> 1.25.0"
|
||||
|
||||
[[audits.semver]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"BUILD.md":"302c5260cb6eb87efc1d968b42f082ea3569cca084c0cbcc1821a8670235c19a","CHANGELOG.md":"9eb97b0c6d9a54cb9a8e317a015c906fccd0400b19802651212b30e1f362497a","CODE_OF_CONDUCT.md":"64765f10290cfce7191b4208cb21698b708a118568f5016602cccc304846a09a","CONTRIBUTING.md":"471d6281fb5038e17e32d3b4450aacf542a396709605aa170e07d3971d70b9c1","Cargo.toml":"60ce8e5e75560df63b4897f5b4d856e1c727de56c4fa4a7ccd90fed8e7b5e059","LICENSE":"f8218253704e32441cafea1b9b3bcb2c6a3c51c5553cd8513d179290202bccb2","Makefile.toml":"3b56a3e8b8d9a8737793dedf02b4c19df0452e20452b9d095c8e0399cb406439","README.md":"14dc4562575c0cde12aeedfdfe1c5adbd90cdbc14168acb6da829a4742becdc6","benches/comparison.rs":"e8b14531b129acb8ffca2dd44565d9160f510ec38abd32fc49fd4e2386067e25","benches/lib_benches.rs":"1525a2b3424e04da73153a0a57f8ee6e3c7ba93f3d847940ee596be57d469248","build.rs":"0ec25a3f820ea04eae1e3caeb0cc422d2f9b53b387553db728dcf2d088a67ab9","rustfmt.toml":"f33bda44a494d17c95b7bc1b3dd88c203030b75be766f3a7f9b63ef45d960bb0","src/arithmetic_impls.rs":"87a87bc46214ba7f239dfafcffb6ca05453f2ff07ed36e94792548d508da7a9d","src/constants.rs":"5a31626a234e4bb1f06752d7db6ebb39a543c5e0df1e929dd0032689ef7aaa1f","src/decimal.rs":"c16606f8b5358611e882d09a26082136845ef18ffd2a3c57cb9c51b393c299d8","src/error.rs":"2a3f31951bcffc3bb3cfb48bb68e0e8f51713b0cd38a441bd4fdfb02228fe9c7","src/fuzz.rs":"86c07d8d541b9ee92a51275993b686902712f94c30785ba93f38997f3569e700","src/lib.rs":"70dbf6c86f99df5d8b6e9d4102ee53e9ad222cbfe8b677ee85afe205165bebee","src/maths.rs":"f82016c5ae8406103835a3fedebeb1360cfe3cc40ac4ab28e13da89636c6782c","src/mysql.rs":"1995123011bda5ac6a7d2df5885a568dfdfecd9897ab8d89205817877a242cb3","src/ops.rs":"4d426a35f73b0b69cbceee6e01c6eff59b8cc09aab7c885570aea52d8f258f66","src/ops/add.rs":"a85b6214be92a5563e8bb4a936275d8de094507d77384c9184d63583a78b3f55","src/ops/array.rs":"17a1af576390c8f33ed6c13e1b62722eeaa24c0c0086fb951def6d5dacfdc1cd","src/ops/cmp.rs":"95437401daf93d60425c388fc243e52ad5570cfe6c5d818b5aa144759a5f2ef1","src/ops/common.rs":"6d48ecfa4796a38cb9d4c48f50ffed5d1ee79ba8e168a175615b6fe97194b7c2","src/ops/div.rs":"6b1e90b383293eb51f20f22846002a61f17211f7791860d4e9d6f82ad940fb87","src/ops/legacy.rs":"08bc45454b1815a592cc2fd02df8c50bec36c831ab7af098018e29dfc81f0ec4","src/ops/mul.rs":"b0bb69461b4934cb53c49e105d21da8aa661e1215e8797b8fdc64564df431d92","src/ops/rem.rs":"125d64e9425effd01d4ff400f811f43ef76bf846b6823195059648fdf004b592","src/postgres.rs":"73c41588262ea8d243a4758596ade35ef902fec7dfaba60c44a40c2456900171","src/rand.rs":"386d5a53feec63f53247f102287a4bf8ffe9dbc464246e5f18bd6b14f15f056d","src/rocket.rs":"4d05f292281e4d463abeba603b07ea460065cb1b8ec1c6dafdb4e41f7b89e828","src/serde.rs":"d04dcd3a2143c7145bdaa917dfac61591f79348134b883d05764993bda5e0bac","src/str.rs":"e6750a1ab197a024bea32e2b31dea86bfb1ad640903d36143396e40864339a27","tests/decimal_tests.rs":"9f9a782cdfb215a0b0d3c191b793c2f14d86b3bde90792a0f512de112c86f43c","tests/macros.rs":"f4e1ade99bf8a7aaf2a2d4ee557df5b0b32266a349daf59b2e8b1ae7bc72599c","tests/version-numbers.rs":"73301b7bfe500eada5ede66f0dce89bd3e354af50a8e7a123b02931cd5eb8e16"},"package":"e2ee7337df68898256ad0d4af4aad178210d9e44d2ff900ce44064a97cd86530"}
|
||||
{"files":{"BUILD.md":"302c5260cb6eb87efc1d968b42f082ea3569cca084c0cbcc1821a8670235c19a","CHANGELOG.md":"1807b647f6d805e7957846be727462418a1c7fcc77995cc02a6f46c9489e2c3e","CODE_OF_CONDUCT.md":"64765f10290cfce7191b4208cb21698b708a118568f5016602cccc304846a09a","CONTRIBUTING.md":"471d6281fb5038e17e32d3b4450aacf542a396709605aa170e07d3971d70b9c1","Cargo.toml":"51d3e23eff65de0d993604235bb2ba346ce48ad11a03ee81c4e46009f0724db3","LICENSE":"f8218253704e32441cafea1b9b3bcb2c6a3c51c5553cd8513d179290202bccb2","Makefile.toml":"759446fa7bc82f7e20333b310204873bf2d7c3a938ed8fd61e4733ffb6e15e32","README.md":"5df24462f65eb1898680080441a178f3918e97841d75f925df38511916dbe0b8","benches/comparison.rs":"e8b14531b129acb8ffca2dd44565d9160f510ec38abd32fc49fd4e2386067e25","benches/lib_benches.rs":"1525a2b3424e04da73153a0a57f8ee6e3c7ba93f3d847940ee596be57d469248","build.rs":"0ec25a3f820ea04eae1e3caeb0cc422d2f9b53b387553db728dcf2d088a67ab9","rustfmt.toml":"f33bda44a494d17c95b7bc1b3dd88c203030b75be766f3a7f9b63ef45d960bb0","src/arithmetic_impls.rs":"87a87bc46214ba7f239dfafcffb6ca05453f2ff07ed36e94792548d508da7a9d","src/constants.rs":"5a31626a234e4bb1f06752d7db6ebb39a543c5e0df1e929dd0032689ef7aaa1f","src/decimal.rs":"9681335e1889d08fae55326b20cd5b863ece5619a238b9c5871ed45f5d88b9e7","src/error.rs":"2a3f31951bcffc3bb3cfb48bb68e0e8f51713b0cd38a441bd4fdfb02228fe9c7","src/fuzz.rs":"86c07d8d541b9ee92a51275993b686902712f94c30785ba93f38997f3569e700","src/lib.rs":"320b247f5b39b309d8a97a76ae58ac0cfd005f88ed3aa7962d8e31c7d3a4733c","src/maths.rs":"f82016c5ae8406103835a3fedebeb1360cfe3cc40ac4ab28e13da89636c6782c","src/mysql.rs":"1995123011bda5ac6a7d2df5885a568dfdfecd9897ab8d89205817877a242cb3","src/ops.rs":"4d426a35f73b0b69cbceee6e01c6eff59b8cc09aab7c885570aea52d8f258f66","src/ops/add.rs":"a85b6214be92a5563e8bb4a936275d8de094507d77384c9184d63583a78b3f55","src/ops/array.rs":"17a1af576390c8f33ed6c13e1b62722eeaa24c0c0086fb951def6d5dacfdc1cd","src/ops/cmp.rs":"95437401daf93d60425c388fc243e52ad5570cfe6c5d818b5aa144759a5f2ef1","src/ops/common.rs":"6d48ecfa4796a38cb9d4c48f50ffed5d1ee79ba8e168a175615b6fe97194b7c2","src/ops/div.rs":"6b1e90b383293eb51f20f22846002a61f17211f7791860d4e9d6f82ad940fb87","src/ops/legacy.rs":"08bc45454b1815a592cc2fd02df8c50bec36c831ab7af098018e29dfc81f0ec4","src/ops/mul.rs":"b0bb69461b4934cb53c49e105d21da8aa661e1215e8797b8fdc64564df431d92","src/ops/rem.rs":"125d64e9425effd01d4ff400f811f43ef76bf846b6823195059648fdf004b592","src/postgres.rs":"73c41588262ea8d243a4758596ade35ef902fec7dfaba60c44a40c2456900171","src/rand.rs":"382f057f4a8752a6028afbecd3cb27422d530c6aa0142ddc04b698b501f8f9db","src/rocket.rs":"4d05f292281e4d463abeba603b07ea460065cb1b8ec1c6dafdb4e41f7b89e828","src/serde.rs":"d04dcd3a2143c7145bdaa917dfac61591f79348134b883d05764993bda5e0bac","src/str.rs":"e6750a1ab197a024bea32e2b31dea86bfb1ad640903d36143396e40864339a27","tests/decimal_tests.rs":"a7ec2edab94d6974677c213b8b6e286772c70e7d81ce76925622dab700c93dea","tests/macros.rs":"f4e1ade99bf8a7aaf2a2d4ee557df5b0b32266a349daf59b2e8b1ae7bc72599c","tests/version-numbers.rs":"73301b7bfe500eada5ede66f0dce89bd3e354af50a8e7a123b02931cd5eb8e16"},"package":"34a3bb58e85333f1ab191bf979104b586ebd77475bc6681882825f4532dfe87c"}
|
|
@ -1,5 +1,15 @@
|
|||
# Version History
|
||||
|
||||
## 1.25.0
|
||||
|
||||
### Added
|
||||
|
||||
* Expands `rand` support to implement `SampleUniform` to allow for `rng.gen_range` calls ([#519](https://github.com/paupino/rust-decimal/pull/519))
|
||||
* Adds [`rkyv` framework](https://github.com/rkyv/rkyv) support for zero-cost (de)serialization ([#520](https://github.com/paupino/rust-decimal/pull/520))
|
||||
|
||||
A big thank you to [@lukesneeringer](https://github.com/lukesneeringer) and [@dovahcrow](https://github.com/dovahcrow) for your help building
|
||||
features for this release.
|
||||
|
||||
## 1.24.0
|
||||
|
||||
* Introduces new feature `rand` which allows for random number generation within `rust_decimal` ([#517](https://github.com/paupino/rust-decimal/pull/517)).
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[package]
|
||||
edition = "2021"
|
||||
name = "rust_decimal"
|
||||
version = "1.24.0"
|
||||
version = "1.25.0"
|
||||
authors = ["Paul Mason <paul@form1.co.nz>"]
|
||||
build = "build.rs"
|
||||
exclude = ["tests/generated/*"]
|
||||
|
@ -57,6 +57,11 @@ version = "0.9.3"
|
|||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.bytecheck]
|
||||
version = "0.6"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.byteorder]
|
||||
version = "1.3"
|
||||
optional = true
|
||||
|
@ -87,6 +92,15 @@ version = "0.8"
|
|||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.rkyv]
|
||||
version = "0.7"
|
||||
features = [
|
||||
"size_32",
|
||||
"std",
|
||||
]
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.rocket]
|
||||
version = "0.5.0-rc.1"
|
||||
optional = true
|
||||
|
@ -186,6 +200,11 @@ default = [
|
|||
legacy-ops = []
|
||||
maths = []
|
||||
maths-nopanic = ["maths"]
|
||||
rkyv-safe = [
|
||||
"bytecheck",
|
||||
"rkyv",
|
||||
"rkyv/validation",
|
||||
]
|
||||
rocket-traits = ["rocket"]
|
||||
rust-fuzz = ["arbitrary"]
|
||||
serde-arbitrary-precision = ["serde-with-arbitrary-precision"]
|
||||
|
|
|
@ -176,7 +176,8 @@ args = ["test", "--workspace", "--no-default-features", "--features=maths-nopani
|
|||
[tasks.test-misc]
|
||||
dependencies = [
|
||||
"test-rust-fuzz",
|
||||
"test-borsh"
|
||||
"test-borsh",
|
||||
"test-rkyv"
|
||||
]
|
||||
|
||||
[tasks.test-rust-fuzz]
|
||||
|
@ -249,9 +250,13 @@ args = ["test", "--workspace", "--tests", "--features=serde-with-str", "serde",
|
|||
|
||||
[tasks.test-borsh]
|
||||
command = "cargo"
|
||||
args = ["test", "--workspace", "--features=borsh"]
|
||||
args = ["test", "--workspace", "--features=borsh", "--", "--skip", "generated"]
|
||||
|
||||
[tasks.test-rkyv]
|
||||
command = "cargo"
|
||||
args = ["test", "--workspace", "--features=rkyv", "--features=rkyv-safe", "--", "--skip", "generated"]
|
||||
|
||||
[tasks.test-rand]
|
||||
command = "cargo"
|
||||
args = ["test", "--workspace", "--features=rand"]
|
||||
args = ["test", "--workspace", "--features=rand", "--", "--skip", "generated"]
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ To get started, add `rust_decimal` and optionally `rust_decimal_macros` to your
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
rust_decimal = "1.24"
|
||||
rust_decimal_macros = "1.24"
|
||||
rust_decimal = "1.25"
|
||||
rust_decimal_macros = "1.25"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
@ -79,6 +79,7 @@ assert_eq!(total.to_string(), "27.26");
|
|||
* [c-repr](#c-repr)
|
||||
* [legacy-ops](#legacy-ops)
|
||||
* [maths](#maths)
|
||||
* [rkyv](#rkyv)
|
||||
* [rocket-traits](#rocket-traits)
|
||||
* [rust-fuzz](#rust-fuzz)
|
||||
* [std](#std)
|
||||
|
@ -144,6 +145,13 @@ non-panicking behavior, please use the feature: `maths-nopanic`.
|
|||
|
||||
Implements `rand::distributions::Distribution<Decimal>` to allow the creation of random instances.
|
||||
|
||||
Note: When using `rand::Rng` trait to generate a decimal between a range of two other decimals, the scale of the randomly-generated
|
||||
decimal will be the same as the scale of the input decimals (or, if the inputs have different scales, the higher of the two).
|
||||
|
||||
### `rkyv`
|
||||
Enables [rkyv](https://github.com/rkyv/rkyv) serialization for `Decimal`.
|
||||
Supports rkyv's safe API when the `rkyv-safe` feature is enabled as well.
|
||||
|
||||
### `rocket-traits`
|
||||
|
||||
Enable support for Rocket forms by implementing the `FromFormField` trait.
|
||||
|
|
|
@ -5,6 +5,8 @@ use crate::constants::{
|
|||
use crate::ops;
|
||||
use crate::Error;
|
||||
|
||||
#[cfg(feature = "rkyv-safe")]
|
||||
use bytecheck::CheckBytes;
|
||||
use core::{
|
||||
cmp::{Ordering::Equal, *},
|
||||
fmt,
|
||||
|
@ -19,6 +21,8 @@ use diesel::sql_types::Numeric;
|
|||
#[cfg(not(feature = "std"))]
|
||||
use num_traits::float::FloatCore;
|
||||
use num_traits::{FromPrimitive, Num, One, Signed, ToPrimitive, Zero};
|
||||
#[cfg(feature = "rkyv")]
|
||||
use rkyv::{Archive, Deserialize, Serialize};
|
||||
|
||||
/// The smallest value that can be represented by this decimal type.
|
||||
const MIN: Decimal = Decimal {
|
||||
|
@ -101,6 +105,13 @@ pub struct UnpackedDecimal {
|
|||
feature = "borsh",
|
||||
derive(borsh::BorshDeserialize, borsh::BorshSerialize, borsh::BorshSchema)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "rkyv",
|
||||
derive(Archive, Deserialize, Serialize),
|
||||
archive(compare(PartialEq)),
|
||||
archive_attr(derive(Debug))
|
||||
)]
|
||||
#[cfg_attr(feature = "rkyv-safe", archive_attr(derive(CheckBytes)))]
|
||||
pub struct Decimal {
|
||||
// Bits 0-15: unused
|
||||
// Bits 16-23: Contains "e", a value between 0-28 that indicates the scale
|
||||
|
|
|
@ -7,7 +7,6 @@ mod constants;
|
|||
mod decimal;
|
||||
mod error;
|
||||
mod ops;
|
||||
mod rand;
|
||||
mod str;
|
||||
|
||||
// We purposely place this here for documentation ordering
|
||||
|
@ -25,6 +24,8 @@ mod mysql;
|
|||
feature = "db-diesel-postgres",
|
||||
))]
|
||||
mod postgres;
|
||||
#[cfg(feature = "rand")]
|
||||
mod rand;
|
||||
#[cfg(feature = "rocket-traits")]
|
||||
mod rocket;
|
||||
#[cfg(all(
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#![cfg(feature = "rand")]
|
||||
|
||||
use crate::Decimal;
|
||||
use rand::{
|
||||
distributions::{Distribution, Standard},
|
||||
distributions::{
|
||||
uniform::{SampleBorrow, SampleUniform, UniformInt, UniformSampler},
|
||||
Distribution, Standard,
|
||||
},
|
||||
Rng,
|
||||
};
|
||||
|
||||
|
@ -21,9 +22,155 @@ impl Distribution<Decimal> for Standard {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_random_decimal_instances() {
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
let random: [Decimal; 32] = rng.gen();
|
||||
assert!(random.windows(2).any(|slice| { slice[0] != slice[1] }));
|
||||
impl SampleUniform for Decimal {
|
||||
type Sampler = DecimalSampler;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct DecimalSampler {
|
||||
mantissa_sampler: UniformInt<i128>,
|
||||
scale: u32,
|
||||
}
|
||||
|
||||
impl UniformSampler for DecimalSampler {
|
||||
type X = Decimal;
|
||||
|
||||
/// Creates a new sampler that will yield random decimal objects between `low` and `high`.
|
||||
///
|
||||
/// The sampler will always provide decimals at the same scale as the inputs; if the inputs
|
||||
/// have different scales, the higher scale is used.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use rand::Rng;
|
||||
/// # use rust_decimal_macros::dec;
|
||||
/// let mut rng = rand::rngs::OsRng;
|
||||
/// let random = rng.gen_range(dec!(1.00)..dec!(2.00));
|
||||
/// assert!(random >= dec!(1.00));
|
||||
/// assert!(random < dec!(2.00));
|
||||
/// assert_eq!(random.scale(), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn new<B1, B2>(low: B1, high: B2) -> Self
|
||||
where
|
||||
B1: SampleBorrow<Self::X> + Sized,
|
||||
B2: SampleBorrow<Self::X> + Sized,
|
||||
{
|
||||
let (low, high) = sync_scales(*low.borrow(), *high.borrow());
|
||||
let high = Decimal::from_i128_with_scale(high.mantissa() - 1, high.scale());
|
||||
UniformSampler::new_inclusive(low, high)
|
||||
}
|
||||
|
||||
/// Creates a new sampler that will yield random decimal objects between `low` and `high`.
|
||||
///
|
||||
/// The sampler will always provide decimals at the same scale as the inputs; if the inputs
|
||||
/// have different scales, the higher scale is used.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use rand::Rng;
|
||||
/// # use rust_decimal_macros::dec;
|
||||
/// let mut rng = rand::rngs::OsRng;
|
||||
/// let random = rng.gen_range(dec!(1.00)..=dec!(2.00));
|
||||
/// assert!(random >= dec!(1.00));
|
||||
/// assert!(random <= dec!(2.00));
|
||||
/// assert_eq!(random.scale(), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
|
||||
where
|
||||
B1: SampleBorrow<Self::X> + Sized,
|
||||
B2: SampleBorrow<Self::X> + Sized,
|
||||
{
|
||||
let (low, high) = sync_scales(*low.borrow(), *high.borrow());
|
||||
|
||||
// Return our sampler, which contains an underlying i128 sampler so we
|
||||
// outsource the actual randomness implementation.
|
||||
Self {
|
||||
mantissa_sampler: UniformInt::new_inclusive(low.mantissa(), high.mantissa()),
|
||||
scale: low.scale(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
|
||||
let mantissa = self.mantissa_sampler.sample(rng);
|
||||
Decimal::from_i128_with_scale(mantissa, self.scale)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return equivalent Decimal objects with the same scale as one another.
|
||||
#[inline]
|
||||
fn sync_scales(mut a: Decimal, mut b: Decimal) -> (Decimal, Decimal) {
|
||||
if a.scale() == b.scale() {
|
||||
return (a, b);
|
||||
}
|
||||
|
||||
// Set scales to match one another, because we are relying on mantissas'
|
||||
// being comparable in order outsource the actual sampling implementation.
|
||||
a.rescale(a.scale().max(b.scale()));
|
||||
b.rescale(a.scale().max(b.scale()));
|
||||
|
||||
// Edge case: If the values have _wildly_ different scales, the values may not have rescaled far enough to match one another.
|
||||
//
|
||||
// In this case, we accept some precision loss because the randomization approach we are using assumes that the scales will necessarily match.
|
||||
if a.scale() != b.scale() {
|
||||
a.rescale(a.scale().min(b.scale()));
|
||||
b.rescale(a.scale().min(b.scale()));
|
||||
}
|
||||
|
||||
(a, b)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::*;
|
||||
|
||||
macro_rules! dec {
|
||||
($e:expr) => {
|
||||
Decimal::from_str_exact(stringify!($e)).unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_random_decimal_instances() {
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
let random: [Decimal; 32] = rng.gen();
|
||||
assert!(random.windows(2).any(|slice| { slice[0] != slice[1] }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generates_within_range() {
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
for _ in 0..128 {
|
||||
let random = rng.gen_range(dec!(1.00)..dec!(1.05));
|
||||
assert!(random < dec!(1.05));
|
||||
assert!(random >= dec!(1.00));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generates_within_inclusive_range() {
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
let mut values: HashSet<Decimal> = HashSet::new();
|
||||
for _ in 0..256 {
|
||||
let random = rng.gen_range(dec!(1.00)..=dec!(1.01));
|
||||
// The scale is 2, so 1.00 and 1.01 are the only two valid choices.
|
||||
assert!(random == dec!(1.00) || random == dec!(1.01));
|
||||
values.insert(random);
|
||||
}
|
||||
// Somewhat flaky, will fail 1 out of every 2^255 times this is run.
|
||||
// Probably acceptable in the real world.
|
||||
assert_eq!(values.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edge_case_scales_match() {
|
||||
let (low, high) = sync_scales(dec!(1.000_000_000_000_000_000_01), dec!(100_000_000_000_000_000_001));
|
||||
assert_eq!(low.scale(), high.scale());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,33 @@ fn it_can_serialize_deserialize_borsh() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "rkyv")]
|
||||
fn it_can_serialize_deserialize_rkyv() {
|
||||
use rkyv::Deserialize;
|
||||
let tests = [
|
||||
"12.3456789",
|
||||
"5233.9008808150288439427720175",
|
||||
"-5233.9008808150288439427720175",
|
||||
];
|
||||
for test in &tests {
|
||||
let a = Decimal::from_str(test).unwrap();
|
||||
let bytes = rkyv::to_bytes::<_, 256>(&a).unwrap();
|
||||
|
||||
#[cfg(feature = "rkyv-safe")]
|
||||
{
|
||||
let archived = rkyv::check_archived_root::<Decimal>(&bytes[..]).unwrap();
|
||||
assert_eq!(archived, &a);
|
||||
}
|
||||
|
||||
let archived = unsafe { rkyv::archived_root::<Decimal>(&bytes[..]) };
|
||||
assert_eq!(archived, &a);
|
||||
|
||||
let deserialized: Decimal = archived.deserialize(&mut rkyv::Infallible).unwrap();
|
||||
assert_eq!(deserialized, a);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_deserialize_unbounded_values() {
|
||||
// Mantissa for these: 19393111376951473493673267553
|
||||
|
@ -2556,14 +2583,14 @@ fn it_can_return_the_min_value() {
|
|||
#[test]
|
||||
fn it_can_go_from_and_into() {
|
||||
let d = Decimal::from_str("5").unwrap();
|
||||
let di8 = 5u8.into();
|
||||
let di32 = 5i32.into();
|
||||
let disize = 5isize.into();
|
||||
let di64 = 5i64.into();
|
||||
let du8 = 5u8.into();
|
||||
let du32 = 5u32.into();
|
||||
let dusize = 5usize.into();
|
||||
let du64 = 5u64.into();
|
||||
let di8: Decimal = 5u8.into();
|
||||
let di32: Decimal = 5i32.into();
|
||||
let disize: Decimal = 5isize.into();
|
||||
let di64: Decimal = 5i64.into();
|
||||
let du8: Decimal = 5u8.into();
|
||||
let du32: Decimal = 5u32.into();
|
||||
let dusize: Decimal = 5usize.into();
|
||||
let du64: Decimal = 5u64.into();
|
||||
|
||||
assert_eq!(d, di8);
|
||||
assert_eq!(di8, di32);
|
||||
|
|
Загрузка…
Ссылка в новой задаче