Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add page to guide about enums #3693

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
27 changes: 27 additions & 0 deletions examples/guide-supported-types-examples/enums.js
@@ -0,0 +1,27 @@
import {
take_number,
take_string,
take_number_option,
take_string_option,
return_number,
return_string,
return_number_option,
return_string_option,
NumberEnum,
// nothing generated for StringEnum :(
} from "./guide_supported_types_examples";

take_number(NumberEnum.Foo);
take_string("spam");

take_number_option(NumberEnum.Bar);
take_number_option(undefined);

take_string_option("eggs");
take_string_option(undefined);

return_number(); // typed as `NumberEnum`
return_string(); // typed as `any`

return_number_option(); // typed as `NumberEnum | undefined`
return_string_option(); // typed as `any | undefined`
47 changes: 47 additions & 0 deletions examples/guide-supported-types-examples/src/enums.rs
@@ -0,0 +1,47 @@
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub enum NumberEnum {
// numbers are optional; default ones will be generated if not provided
Foo = 0,
Bar = 1,
Baz = 2,
}

#[wasm_bindgen]
pub enum StringEnum {
Spam = "spam",
Eggs = "eggs",
}

#[wasm_bindgen]
pub fn take_number(x: NumberEnum) {}

#[wasm_bindgen]
pub fn take_string(x: StringEnum) {}

#[wasm_bindgen]
pub fn take_number_option(x: Option<NumberEnum>) {}

#[wasm_bindgen]
pub fn take_string_option(x: Option<StringEnum>) {}

#[wasm_bindgen]
pub fn return_number() -> NumberEnum {
todo!()
}

#[wasm_bindgen]
pub fn return_string() -> StringEnum {
todo!()
}

#[wasm_bindgen]
pub fn return_number_option() -> Option<NumberEnum> {
todo!()
}

#[wasm_bindgen]
pub fn return_string_option() -> Option<StringEnum> {
todo!()
}
1 change: 1 addition & 0 deletions examples/guide-supported-types-examples/src/lib.rs
Expand Up @@ -4,6 +4,7 @@ pub mod bool;
pub mod boxed_js_value_slice;
pub mod boxed_number_slices;
pub mod char;
pub mod enums;
pub mod exported_types;
pub mod imported_types;
pub mod js_value;
Expand Down
6 changes: 5 additions & 1 deletion guide/src/SUMMARY.md
Expand Up @@ -2,7 +2,7 @@

[Introduction](./introduction.md)

--------------------------------------------------------------------------------
---

- [Examples](./examples/index.md)
- [Hello, World!](./examples/hello-world.md)
Expand Down Expand Up @@ -32,6 +32,7 @@
- [Wasm Audio Worklet](./examples/wasm-audio-worklet.md)
- [web-sys: A TODO MVC App](./examples/todomvc.md)
- [Reference](./reference/index.md)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add the spaces here?
Seems inconsistent with the rest.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk vscode auto-formatter just doing whatever it wants

- [Deployment](./reference/deployment.md)
- [JS snippets](./reference/js-snippets.md)
- [Static JS Objects](./reference/static-js-objects.md)
Expand Down Expand Up @@ -59,6 +60,7 @@
- [`char`](./reference/types/char.md)
- [`str`](./reference/types/str.md)
- [`String`](./reference/types/string.md)
- [`enum`](./reference/types/enum.md)
- [Number Slices](./reference/types/number-slices.md)
- [Boxed Number Slices](./reference/types/boxed-number-slices.md)
- [`Result<T, E>`](./reference/types/result.md)
Expand Down Expand Up @@ -98,6 +100,7 @@
- [`getter_with_clone`](./reference/attributes/on-rust-exports/getter_with_clone.md)

- [`web-sys`](./web-sys/index.md)

- [Using `web-sys`](./web-sys/using-web-sys.md)
- [Cargo Features](./web-sys/cargo-features.md)
- [Function Overloads](./web-sys/function-overloads.md)
Expand All @@ -106,6 +109,7 @@
- [Unstable APIs](./web-sys/unstable-apis.md)

- [Testing with `wasm-bindgen-test`](./wasm-bindgen-test/index.md)

- [Usage](./wasm-bindgen-test/usage.md)
- [Writing Asynchronous Tests](./wasm-bindgen-test/asynchronous-tests.md)
- [Testing in Headless Browsers](./wasm-bindgen-test/browsers.md)
Expand Down
72 changes: 72 additions & 0 deletions guide/src/reference/types/enum.md
@@ -0,0 +1,72 @@
# enum

| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
| :-----------: | :------------: | :----------------: | :--------------: | :-------------------: | :----------------------: | :-----------------------: |
| Yes | No | No | Yes | Yes | Yes | `string` or `number` |

## Example Rust Usage

```rust
{{#include ../../../../examples/guide-supported-types-examples/src/enums.rs}}
```

## Example JavaScript Usage

```js
{{#include ../../../../examples/guide-supported-types-examples/enums.js}}
```

## TypeScript

Unfortunately, string enums don't fully work yet; no TypeScript is generated for the enum itself and functions using them accept or return `any`.
They work correctly, it's just there's no type hints.
See [Issue #3057](https://github.com/rustwasm/wasm-bindgen/issues/3057)
Comment on lines +21 to +23
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Unfortunately, string enums don't fully work yet; no TypeScript is generated for the enum itself and functions using them accept or return `any`.
They work correctly, it's just there's no type hints.
See [Issue #3057](https://github.com/rustwasm/wasm-bindgen/issues/3057)
Note that string enums currently don't generate a type and instead use `any`.

Let's keep the language neutral like in the rest of the documentation.
Also I don't believe we link to issues in the rest of the documentation as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to link it so it doesn't go out of date. i agree on the wording change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like if string enums get fixed and the documentation doesn't get updated, hopefully someone will open the issue, see that it's completed, and realize "oh, the documentation must be outdated"


The generated TypeScript declarations for the above:

<!-- remember to keep this up to date! copy enum.rs (above) into the lib.rs file of a new wasm-bindgen crate; use `wasm-pack build`; then copy pkg/testcrate.d.ts. also ran it through a formatter. -->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep this consistent in the future: is the formatter really necessary?


```ts
/**
* @param {NumberEnum} x
*/
export function take_number(x: NumberEnum): void;
/**
* @param {any} x
*/
export function take_string(x: any): void;
/**
* @param {NumberEnum | undefined} [x]
*/
export function take_number_option(x?: NumberEnum): void;
/**
* @param {any | undefined} [x]
*/
export function take_string_option(x?: any): void;
/**
* @returns {NumberEnum}
*/
export function return_number(): NumberEnum;
/**
* @returns {any}
*/
export function return_string(): any;
/**
* @returns {NumberEnum | undefined}
*/
export function return_number_option(): NumberEnum | undefined;
/**
* @returns {any | undefined}
*/
export function return_string_option(): any | undefined;
/**
*/
export enum NumberEnum {
Foo = 0,
Bar = 1,
Baz = 2,
}

// no types generated for StringEnum (yet) :(
// see the note above
Comment on lines +69 to +71
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// no types generated for StringEnum (yet) :(
// see the note above

I don't think this is necessary given the above note.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worry probably too much about someone scrolling past the prose and just reading the examples
(because i would do that exact thing)

```