diff --git a/guide/src/reference/types/bool.md b/guide/src/reference/types/bool.md index 6859de8c249..0ef43029250 100644 --- a/guide/src/reference/types/bool.md +++ b/guide/src/reference/types/bool.md @@ -4,6 +4,10 @@ |:---:|:---:|:---:|:---:|:---:|:---:|:---:| | Yes | No | No | Yes | Yes | Yes | A JavaScript boolean value | +> **Note**: Only [JavaScript `Boolean`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) values (`true` or `false`) are supported when calling into Rust. If you want to pass truthy or falsy values to Rust, convert them to a boolean using `Boolean(value)` first. +> +> If you are using TypeScript, you don't have to worry about this, as TypeScript will emit a compiler error if you try to pass a non-`boolean` value. + ## Example Rust Usage ```rust diff --git a/guide/src/reference/types/boxed-number-slices.md b/guide/src/reference/types/boxed-number-slices.md index 73cbf0d1891..6df85e18287 100644 --- a/guide/src/reference/types/boxed-number-slices.md +++ b/guide/src/reference/types/boxed-number-slices.md @@ -4,7 +4,7 @@ |:---:|:---:|:---:|:---:|:---:|:---:|:---:| | Yes | No | No | Yes | Yes | Yes | A JavaScript `TypedArray` of the appropriate type (`Int32Array`, `Uint8Array`, etc...) | -Note that the contents of the slice are copied into the JavaScript `TypedArray` +> **Note:** The contents of the slice are copied into a JavaScript [`TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) from the Wasm linear memory when returning a boxed slice to JavaScript, and vice versa when receiving a JavaScript `TypedArray` as a boxed slice in Rust. diff --git a/guide/src/reference/types/char.md b/guide/src/reference/types/char.md index 168f93191b3..c8e726ac6ab 100644 --- a/guide/src/reference/types/char.md +++ b/guide/src/reference/types/char.md @@ -4,6 +4,14 @@ |:---:|:---:|:---:|:---:|:---:|:---:|:---:| | Yes | No | No | Yes | No | No | A JavaScript string value | +Since JavaScript doesn't have a character type, `char` is represented as a JavaScript string with one Unicode code point. + +> **Note**: [JavaScript strings uses UTF-16 encoding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#utf-16_characters_unicode_code_points_and_grapheme_clusters). This means that a single `char` may be represented by a string of length 1 or 2 in JavaScript, depending on the Unicode code point. See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) for more information. + +When passed into Rust, the `char` value of a JavaScript string is determined using [`codePointAt(0)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt). If the JavaScript string is empty or starts with an unpaired surrogate, a runtime error will be thrown. + +> **Note**: For more information about unpaired surrogates, see the [documentation for `str`](str.html). + ## Example Rust Usage ```rust diff --git a/guide/src/reference/types/exported-rust-types.md b/guide/src/reference/types/exported-rust-types.md index deaad2fb359..2e190db43ae 100644 --- a/guide/src/reference/types/exported-rust-types.md +++ b/guide/src/reference/types/exported-rust-types.md @@ -4,9 +4,10 @@ |:---:|:---:|:---:|:---:|:---:|:---:|:---:| | Yes | Yes | Yes | Yes | Yes | Yes | Instances of a `wasm-bindgen`-generated JavaScript `class Whatever { ... }` | -> **Note**: Public fields implementing Copy have automatically generated getters/setters. -> To generate getters/setters for non-Copy public fields, use #[wasm_bindgen(getter_with_clone)] for the struct +> **Note**: Public fields implementing `Copy` have automatically generated getters/setters. +> To generate getters/setters for non-`Copy` public fields, use `#[wasm_bindgen(getter_with_clone)]` for the struct > or [implement getters/setters manually](https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-rust-exports/getter-and-setter.html). + ## Example Rust Usage ```rust diff --git a/guide/src/reference/types/numbers.md b/guide/src/reference/types/numbers.md index 13742f53fd2..0444fdc82c5 100644 --- a/guide/src/reference/types/numbers.md +++ b/guide/src/reference/types/numbers.md @@ -2,7 +2,58 @@ | `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option` parameter | `Option` return value | JavaScript representation | |:---:|:---:|:---:|:---:|:---:|:---:|:---:| -| Yes | No | No | Yes | Yes | Yes | A JavaScript number value | +| Yes | No | No | Yes | Yes | Yes | A JavaScript number or bigint value | + +[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: + +- `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, `usize`, `f32`, and `f64` will be represented as `Number` in JavaScript. +- `u64` and `i64` will be represented as `BigInt` in JavaScript. + +> **Note**: Wasm is currently a 32-bit architecture, so `isize` and `usize` are 32-bit integers and "fit" into a JavaScript `Number`. + +## Converting from JavaScript to Rust + +`wasm-bindgen` will automatically handle the conversion of JavaScript numbers to Rust numeric types. The conversion rules are as follows: + +### `Number` to `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, and `usize` + +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. + +For example, if the target type is `i8`, Rust will see the following values for the following inputs: + +| JS input number | Rust value (`i8`) | +| --------------: | :---------------- | +| 42 | 42 | +| -42 | -42 | +| 1.999 | 1 | +| -1.999 | -1 | +| 127 | 127 | +| 128 | -128 | +| 255 | -1 | +| 256 | 0 | +| -0 | 0 | +| `±Infinity` | 0 | +| `NaN` | 0 | + +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]`. + +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`. + +### `BigInt` to `u64` and `i64` + +If the JavaScript `BigInt` is too large or too small for the target integer type, it will wrap around. + +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]`. + +### `Number` to `f32` + +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`. + +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]`. + +### `Number` to `f64` + +Since JavaScript numbers are 64-bit floating point values, converting a JavaScript `Number` to a Rust `f64` is a no-op. ## Example Rust Usage