wasm-bindgen icon indicating copy to clipboard operation
wasm-bindgen copied to clipboard

Implement array! and json! proc macros to make creation/instantiation easier

Open dcechano opened this issue 6 months ago • 1 comments

This PR merges two proc macros that make js_sys::Array and js_sys::Object creation and instantiation easier.

Currently, to create an Object, you must use the Reflect API. Retrieving a property requires a Reflect::get call for every attempted retrieval. Likewise, to add a key-value pair to an Object, we must make a Reflect::set call for every property we would like to set. If we are adding an Object to another Object, that Object must be instantiated the same way before finally setting it in the target Object. This process is very cumbersome and quickly clutters the code.

The json! and array! proc macros address this problem. json! allows the creation of a js_sys::Object using JavaScript object literal syntax:

let john = json! {
    name: "John",
    age: 26
};

let has_name = Object::has_own_property(&john, &"name".into());
let has_age = Object::has_own_property(&john, &"age".into());
assert!(has_name);
assert!(has_age);

Similarly, the array! macro facilitates the creation of js_sys::Arrays using JavaScript array literal syntax:

let arr = array![1, 2, 3];
let expected = Array::of3(&1.into(), &2.into(), &3.into());
assert_eq!(arr.get(0).as_f64().unwrap(), expected.get(0).as_f64().unwrap());
assert_eq!(arr.get(1).as_f64().unwrap(), expected.get(1).as_f64().unwrap());
assert_eq!(arr.get(2).as_f64().unwrap(), expected.get(2).as_f64().unwrap());

Both macros support the use of variables in the JSON as long as the underlying type implements Into<JsValue>. Comments are also supported. I have been thinking about how useful a macro like this could be for quite some time, and I finally decided to implement it. Please check out the README.md for more information, as I've only covered the basics here. Let me know your thoughts!

dcechano avatar May 31 '25 05:05 dcechano

@dcechano Great feature 🚀 Could you fix the tests and checks?

reneleonhardt avatar Jun 19 '25 09:06 reneleonhardt

@dcechano Great feature 🚀 Could you fix the tests and checks?

Thanks! The CI issues, however, appear to be unrelated to my changes. They even happen on the main branch. The CI issues definitely need to be fix but ideally should be fixed in a separate PR.

dcechano avatar Jun 25 '25 09:06 dcechano

@daxpedda https://github.com/rustwasm/wasm-bindgen/actions/runs/15360754943/job/43227531304?pr=4515#step:5:52 Who can fix the deprecations to allow CI to be green again?

Error: extern declarations without an explicit ABI are deprecated
   --> src/closure.rs:663:24
    |
663 |                   unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
    |                          ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`

reneleonhardt avatar Jun 25 '25 14:06 reneleonhardt

Just updated the branch, with CI which should be passing now. If you want to add a changelog entry here it would be nice to add.

guybedford avatar Aug 08 '25 16:08 guybedford

Generally we would like to keep quality-of-life features like this out of wasm-bindgen. We are trying to stick to this being only a bindings library (there's a spectrum here ofc).

Seeing as this could be entirely implemented externally, I would like to encourage you to package this up and release it as a standalone crate.

We just discussed having some sort of page for community projects, a library like this could find a place there.

Thank you!

dcechano avatar Sep 18 '25 14:09 dcechano

Closing since maintainers have expressed that this feature may be better placed in a separate library.

dcechano avatar Sep 18 '25 14:09 dcechano

Thank you for your great contribution and quality-of-life macros @dcechano, so sad it will never be a part of wasm-bindgen to make it so much easier for developers 😞

reneleonhardt avatar Sep 18 '25 15:09 reneleonhardt

Thank you for your great contribution and quality-of-life macros @dcechano, so sad it will never be a part of wasm-bindgen to make it so much easier for developers 😞

Maybe I will make a small crate and publish it to crates.io.

dcechano avatar Sep 18 '25 16:09 dcechano

@dcechano please do share what you work on here, and we'd be happy to feature it in the docs.

guybedford avatar Sep 18 '25 17:09 guybedford