wasm-bindgen
wasm-bindgen copied to clipboard
Proposal: Use Symbol for trait impls
Motivation
Currently, #[wasm_bindgen]
cannot be applied to trait impls, I guess this is to avoid method name collision? If that is the case, then JavaScript Symbol is a perfect solution for this.
Proposed Solution
Convert trait methods to JavaScript methods with symbols for names, and trait names can be converted to a namespace object of symbols. For example:
This code:
// src/lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct Foo {
value: i32,
}
#[wasm_bindgen]
impl Foo {
#[wasm_bindgen(constructor)]
pub fn new(value: i32) -> Self {
Foo { value }
}
#[wasm_bindgen]
pub fn read(&self) -> i32 {
self.value
}
}
#[wasm_bingen]
trait Read {
fn read(&self) -> i32;
}
#[wasm_bindgen]
impl Read for Foo {
#[wasm_bindgen]
fn read(&self) -> i32 {
self.value
}
}
can be converted to this TypeScript declaration:
// from Read trait in the Rust source
// all Rust structs that impl Read trait will be converted to TypeScript classes that implements Read interface
export interface Read {
// from Read::read in the Rust source
[Read.read](this: this): number
}
// from Read trait in the Rust source
// namespaces in TypeScript are just objects in JavaScript
export declare namespace Read {
// from Read::read in the Rust source
const read: unique symbol;
type read = typeof read;
}
export declare class Foo implements Read {
public constructor(value: number);
public read(this: Foo): number;
// from Read::read in the Rust source
public [Read.read](this: this): number;
}
[!NOTE] In the JavaScript glue code,
Read
object must always be created beforeclass Foo
.