|
2 | 2 |
|
3 | 3 | | `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|
4 | 4 | |:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
5 |
| -| Yes | No | No | Yes | Yes | Yes | A JavaScript number value | |
| 5 | +| Yes | No | No | Yes | Yes | Yes | A JavaScript number or bigint value | |
| 6 | + |
| 7 | +[JavaScript `Number`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_encoding) are 64-bit floating point value under the hood and cannot accurately represent all of Rust's numeric types. `wasm-bindgen` will automatically use either [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) or `Number` to accurately represent Rust's numeric types in JavaScript: |
| 8 | + |
| 9 | +- `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, `usize`, `f32`, and `f64` will be represented as `Number` in JavaScript. |
| 10 | +- `u64` and `i64` will be represented as `BigInt` in JavaScript. |
| 11 | + |
| 12 | +> **Note**: Wasm is currently a 32-bit architecture, so `isize` and `usize` are 32-bit integers and "fit" into a JavaScript `Number`. |
| 13 | +
|
| 14 | +## Converting from JavaScript to Rust |
| 15 | + |
| 16 | +`wasm-bindgen` will automatically handle the conversion of JavaScript numbers to Rust numeric types. The conversion rules are as follows: |
| 17 | + |
| 18 | +### `Number` to `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, and `usize` |
| 19 | + |
| 20 | +If the JavaScript number is `Infinity`, `-Infinity`, or `NaN`, then the Rust value will be 0. Otherwise, the JavaScript number will rounded towards zero (see [`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) or [`f64::trunc`](https://doc.rust-lang.org/std/primitive.f64.html#method.trunc)). If the rounded number is too large or too small for the target integer type, it will wrap around. |
| 21 | + |
| 22 | +For example, if the target type is `i8`, Rust will see the following values for the following inputs: |
| 23 | + |
| 24 | +| JS input number | Rust value (`i8`) | |
| 25 | +| --------------: | :---------------- | |
| 26 | +| 42 | 42 | |
| 27 | +| -42 | -42 | |
| 28 | +| 1.999 | 1 | |
| 29 | +| -1.999 | -1 | |
| 30 | +| 127 | 127 | |
| 31 | +| 128 | -128 | |
| 32 | +| 255 | -1 | |
| 33 | +| 256 | 0 | |
| 34 | +| -0 | 0 | |
| 35 | +| `±Infinity` | 0 | |
| 36 | +| `NaN` | 0 | |
| 37 | + |
| 38 | +This is the same behavior as assigning the JavaScript `Number` to a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) of the appropriate integer type in JavaScript, i.e. `new Uint8Array([value])[0]`. |
| 39 | + |
| 40 | +Except for the handling of `Infinity` and `-Infinity`, this is the same behavior as [casting](https://doc.rust-lang.org/reference/expressions/operator-expr.html#numeric-cast) `f64` to the appropriate integer type in Rust, i.e. `value_f64 as u32`. |
| 41 | + |
| 42 | +### `BigInt` to `u64` and `i64` |
| 43 | + |
| 44 | +If the JavaScript `BigInt` is too large or too small for the target integer type, it will wrap around. |
| 45 | + |
| 46 | +This is the same behavior as assigning the JavaScript `BigInt` to a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) of the appropriate integer type in JavaScript, i.e. `new Int64Array([value])[0]`. |
| 47 | + |
| 48 | +### `Number` to `f32` |
| 49 | + |
| 50 | +The JavaScript `Number` is converted to a Rust `f32` using the same rules as [casting](https://doc.rust-lang.org/reference/expressions/operator-expr.html#numeric-cast) `f64` to `f32` in Rust, i.e. `value_f64 as f32`. |
| 51 | + |
| 52 | +This is the same behavior as [`Math.fround`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround) or assigning the JavaScript `Number` to a [`Float32Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array) in JavaScript, i.e. `new Float32Array([value])[0]`. |
| 53 | + |
| 54 | +### `Number` to `f64` |
| 55 | + |
| 56 | +Since JavaScript numbers are 64-bit floating point values, converting a JavaScript `Number` to a Rust `f64` is a no-op. |
6 | 57 |
|
7 | 58 | ## Example Rust Usage
|
8 | 59 |
|
|
0 commit comments