Skip to content

Commit 42f22f5

Browse files
committed
add array! and json! proc macros
1 parent c35cc93 commit 42f22f5

File tree

7 files changed

+1279
-0
lines changed

7 files changed

+1279
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ exclude = ["crates/msrv/resolver", "crates/msrv/lib", "crates/msrv/cli"]
8989
members = [
9090
"benchmarks",
9191
"crates/cli",
92+
"crates/creation-macros",
9293
"crates/js-sys",
9394
"crates/test",
9495
"crates/test/sample",

crates/creation-macros/Cargo.toml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
[package]
2+
authors = ["The wasm-bindgen Developers"]
3+
categories = ["wasm"]
4+
description = """
5+
Convenience macros for creating Javascript objects and arrays. For more
6+
information see https://github.com/rustwasm/wasm-bindgen.
7+
"""
8+
documentation = "https://rustwasm.github.io/wasm-bindgen/"
9+
edition = "2021"
10+
homepage = "https://rustwasm.github.io/wasm-bindgen/"
11+
include = ["/LICENSE-*", "/src"]
12+
license = "MIT OR Apache-2.0"
13+
name = "wasm-bindgen-creation-macros"
14+
repository = "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/creation-macros"
15+
rust-version = "1.76"
16+
version = "0.2.100"
17+
18+
[lib]
19+
proc-macro = true
20+
21+
[dependencies]
22+
proc-macro2 = "1.0.95"
23+
quote = "1.0.40"
24+
syn = "2.0.101"
25+
26+
[dev-dependencies]
27+
wasm-bindgen = { path = "../../" }
28+
js-sys = { path = "../js-sys" }
29+
30+
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
31+
wasm-bindgen-test = { path = '../test' }
32+
33+
[lints]
34+
workspace = true
35+
36+
[[test]]
37+
name = "creation"
38+
path = "tests/creation.rs"

crates/creation-macros/LICENSE-APACHE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-APACHE

crates/creation-macros/LICENSE-MIT

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-MIT

crates/creation-macros/README.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# wasm-bindgen-creation-macros
2+
3+
This crate provides procedural macros for the `wasm-bindgen` project, specifically focused on code generation and WebAssembly bindings creation.
4+
5+
## Overview
6+
7+
The `json!` and `array!` macros help in the creation of `js_sys::Object` and `js_sys::Array`, respectively. Specifically, they cut down on the verbose repetitive code needed to initialize `Object` and `Array` objects using plain Rust. Both macros support the use of any literals or variables that implement [`Into<JsValue>`](https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html#trait-implementations). That includes rust strings, floating point numbers and integers, etc.
8+
9+
### Examples
10+
11+
```rust
12+
use wasm_bindgen::prelude::*;
13+
use js_sys::{Array, Object};
14+
use wasm_bindgen_creation_macros::{array, json};
15+
16+
fn create_person() -> Object {
17+
let address = json! {
18+
street: "123 Main St",
19+
city: "Tech City",
20+
country: "Rustland"
21+
};
22+
23+
json! {
24+
name: "Alice",
25+
age: 30,
26+
hobbies: ["reading", "coding", "hiking"],
27+
address: address, // Note the use of a variable!
28+
fav_floats: [ 1.618, 3.14, 2.718 ],
29+
nested_obj: {
30+
num: 42,
31+
inner_obj: {
32+
msg: "Arbitrary nesting is supported!"
33+
}
34+
}
35+
}
36+
}
37+
38+
fn create_numbers() -> Array {
39+
// variables work in array! as well.
40+
const FIVE: u32 = 5;
41+
array![1, 2, 3, 4, FIVE]
42+
}
43+
44+
// Since variables are supported, array! and json! can be
45+
// used together to create complex objects.
46+
fn mix_and_match() -> Object {
47+
let evens = array![2, 4, 6, 8];
48+
let odds = array![1, 3, 6, 7];
49+
50+
let rust = json! {
51+
language: "Rust",
52+
mascot: "Crab"
53+
};
54+
55+
let go = json! {
56+
language: "Go",
57+
mascot: "Gopher"
58+
};
59+
60+
let languages_array = array![ rust, go, { language: "Python", mascot: "Snakes" } ];
61+
62+
json! {
63+
evens: evens,
64+
odds: odds,
65+
languages: languages_array
66+
}
67+
}
68+
```
69+
70+
## A Note on Parsing
71+
72+
The parser used is not sophisticated; Rust values that are not **simple** Rust literals should be stored in a variable first, then the variable should be added to the macro. Attempting to pass non-simple rust syntax will cause compilation to fail.
73+
74+
```rust
75+
use wasm_bindgen::prelude::*;
76+
use js_sys::{Array, Object};
77+
use wasm_bindgen_creation_macros::{array, json};
78+
79+
pub struct CustomJsValue(u32);
80+
81+
impl Into<JsValue> for CustomJsValue {
82+
fn into(self) -> JsValue {
83+
self.0.into()
84+
}
85+
}
86+
87+
// WILL NOT COMPILE
88+
fn incorrect() -> Object {
89+
json! {
90+
custom: CustomJsValue(42)
91+
}
92+
}
93+
94+
// Do this instead
95+
fn correct() -> Object {
96+
let custom = CustomJsValue(42);
97+
json! {
98+
js_value: custom
99+
}
100+
}
101+
102+
// WILL NOT COMPILE
103+
fn also_invalid() -> Object {
104+
json! {
105+
array: array![1, 2, 3]
106+
}
107+
}
108+
109+
// Do this instead
110+
fn also_correct() -> Object {
111+
let array = array![1, 2, 3];
112+
json! {
113+
array: array
114+
}
115+
116+
}
117+
```
118+
119+
Also, `json!` does not (currently) support string literal JSON keys.
120+
121+
122+
```rust
123+
use wasm_bindgen::prelude::*;
124+
use js_sys::{Array, Object};
125+
use wasm_bindgen_creation_macros::{array, json};
126+
127+
// WILL NOT COMPILE
128+
fn incorrect() -> Object {
129+
json! {
130+
"key": 42
131+
}
132+
}
133+
134+
// Do this instead
135+
fn correct() -> Object {
136+
json! {
137+
key: 42
138+
}
139+
}
140+
```
141+
142+
## Testing
143+
To run the test suite, run `cargo test --target wasm32-unknown-unknown`.
144+
145+
```bash
146+
cargo test --target wasm32-unknown-unknown
147+
```

0 commit comments

Comments
 (0)