Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ranile/ducktor
A macro to generate constructor to instanicate structs from JsValue using duck-typing.
https://github.com/ranile/ducktor
duck-typing rust wasm-bindgen
Last synced: about 1 month ago
JSON representation
A macro to generate constructor to instanicate structs from JsValue using duck-typing.
- Host: GitHub
- URL: https://github.com/ranile/ducktor
- Owner: ranile
- License: mit
- Created: 2023-06-21T18:15:52.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2023-09-10T11:26:18.000Z (about 1 year ago)
- Last Synced: 2024-09-13T06:00:32.761Z (2 months ago)
- Topics: duck-typing, rust, wasm-bindgen
- Language: Rust
- Homepage: https://crates.io/crates/ducktor
- Size: 17.6 KB
- Stars: 9
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ducktor
ducktor is a Rust crate that allows you to create types from `wasm_bindgen::JsValue` using duck typing.
With ducktor, you can define a struct that specifies the fields and types that you expect from a JsValue, and then use
the implement `From` for it using the `#[derive(FromJsValue)]` macro. This way, you can use Rust's type
system and syntax to work with JavaScript objects in WebAssembly.## Why
- Using`#[wasm_bindgen]` on exported types requires the input on an exported function be of the class created
by `wasm-bindgen` which is not always possible
- Using imported types with `#[wasm_bindgen] extern "C" { ... }` makes it so that the type is not creatable from Rust.
This becomes a problem in shared code where you want to create instance of the type from Rust as well.## Solution
Meet ducktor! A constructor for your structs using duck typing. It allows you to create a struct, as you normally would.
Then, you can use the `#[derive(FromJsValue)]` macro to implement `From` for your struct. This allows you to
use
the `from` method on your struct to create an instance of it from a `JsValue`.Internally, it defines and imports a non-existent JavaScript type that matches the struct fields and types.
The `JsValue` is then coerced into this type using `JsValue::unchecked_ref` and then the struct is created by getting
the value of each field from the JS type.## Example
```rust
use ducktor::FromJsValue;// Define a struct that represents a JavaScript object with an a field and a b field
#[derive(FromJsValue)]
struct Data {
a: u32,
b: String,
}// Create a JavaScript object that conforms to the Data struct
fn roundtrip() {
let data = js_sys::Object::new();
js_sys::Reflect::set(&data, &"a".into(), &42.into()).unwrap();
js_sys::Reflect::set(&data, &"b".into(), &"string".into()).unwrap();// Convert the JsValue to a Data using the `from_js_value` method
let data: Data = Data::from(&data.into());
assert_eq!(data.a, 42);
assert_eq!(data.b, "string");
}
```