Skip to content

Commit 587addd

Browse files
Add wasm support to rust-decimal
A new optional feature 'wasm' has been introduced in the codebase. This enables `wasm-bindgen` support, making `Decimal` compatible with the `wasm_bindgen` attribute macro, and exposes `fromNumber()` and `toNumber()` methods to convert between `Decimal` and the primitive `number` type.
1 parent c5d4afe commit 587addd

File tree

5 files changed

+40
-0
lines changed

5 files changed

+40
-0
lines changed

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ rocket = { default-features = false, optional = true, version = "0.5.0-rc.3" }
3636
serde = { default-features = false, optional = true, version = "1.0" }
3737
serde_json = { default-features = false, optional = true, version = "1.0" }
3838
tokio-postgres = { default-features = false, optional = true, version = "0.7" }
39+
wasm-bindgen = { default-features = false, optional = true, version = "0.2" }
3940

4041
[dev-dependencies]
4142
bincode = { default-features = false, version = "1.0" }
@@ -85,6 +86,7 @@ serde-with-float = ["serde"]
8586
serde-with-str = ["serde"]
8687
std = ["arrayvec/std", "borsh?/std", "bytes?/std", "rand?/std", "rkyv?/std", "serde?/std", "serde_json?/std"]
8788
tokio-pg = ["db-tokio-postgres"] # Backwards compatability
89+
wasm = ["dep:wasm-bindgen"]
8890

8991
[[bench]]
9092
harness = false

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ assert_eq!(total, dec!(27.26));
104104
* [rocket-traits](#rocket-traits)
105105
* [rust-fuzz](#rust-fuzz)
106106
* [std](#std)
107+
* [wasm](#wasm)
107108

108109
**Database**
109110

@@ -331,6 +332,12 @@ Please see the `examples` directory for more information regarding `serde_json`
331332
Enable `std` library support. This is enabled by default, however in the future will be opt in. For now, to support `no_std`
332333
libraries, this crate can be compiled with `--no-default-features`.
333334

335+
### `wasm`
336+
337+
Enable [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) support which makes `Decimal` compatible with the
338+
`wasm_bindgen` attribute macro and exposes `fromNumber()` and `toNumber()` methods to convert between `Decimal` and
339+
the primitive `number` type across boundaries.
340+
334341
## Building
335342

336343
Please refer to the [Build document](BUILD.md) for more information on building and testing Rust Decimal.

src/decimal.rs

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ use num_traits::float::FloatCore;
2727
use num_traits::{FromPrimitive, Num, One, Signed, ToPrimitive, Zero};
2828
#[cfg(feature = "rkyv")]
2929
use rkyv::{Archive, Deserialize, Serialize};
30+
#[cfg(feature = "wasm")]
31+
use wasm_bindgen::prelude::wasm_bindgen;
3032

3133
/// The smallest value that can be represented by this decimal type.
3234
const MIN: Decimal = Decimal {
@@ -121,6 +123,7 @@ pub struct UnpackedDecimal {
121123
archive_attr(derive(Clone, Copy, Debug))
122124
)]
123125
#[cfg_attr(feature = "rkyv-safe", archive(check_bytes))]
126+
#[cfg_attr(feature = "wasm", wasm_bindgen)]
124127
pub struct Decimal {
125128
// Bits 0-15: unused
126129
// Bits 16-23: Contains "e", a value between 0-28 that indicates the scale

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ mod serde;
5252
)
5353
))]
5454
pub mod serde;
55+
#[cfg(feature = "wasm")]
56+
pub mod wasm;
5557

5658
pub use decimal::{Decimal, RoundingStrategy};
5759
pub use error::Error;

src/wasm.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use num_traits::{FromPrimitive, ToPrimitive};
2+
use wasm_bindgen::prelude::wasm_bindgen;
3+
4+
use crate::Decimal;
5+
6+
#[wasm_bindgen]
7+
impl Decimal {
8+
/// Returns a new `Decimal` object instance by converting a primitive number.
9+
#[wasm_bindgen(js_name = fromNumber)]
10+
#[must_use]
11+
pub fn from_number(value: f64) -> Option<Decimal> {
12+
Decimal::from_f64(value)
13+
}
14+
15+
/// Returns the value of this `Decimal` converted to a primitive number.
16+
///
17+
/// # Caution
18+
/// At the time of writing this implementation the conversion from `Decimal` to `f64` cannot
19+
/// fail. To prevent undefined behavior in case the underlying implementation changes `f64::NAN`
20+
/// is returned as a stable fallback value.
21+
#[wasm_bindgen(js_name = toNumber)]
22+
#[must_use]
23+
pub fn to_number(&self) -> f64 {
24+
self.to_f64().unwrap_or(f64::NAN)
25+
}
26+
}

0 commit comments

Comments
 (0)