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,
Readobject must always be created beforeclass Foo.
Alternatives
Additional Context
Currently there isn't support for traits mostly because no one's worked on it yet, not necesesarily because of symbol collisions. Implementing this seems fine to me though, and I'd be curious to see what it would look like!
I have a lot of interwined enums, and enums cant have methods for wasm_bindgen, so this for simplifying a lot of utils would be awesome
Tl;dr: Looking for a mentor for a first open source contribution for this issue
I am new to wasm and have been learning about wasm-bindgen. I’ve been focusing on using wasm-bindgen to port types over to JavaScript so that Rust libraries that can be used in the front-end. The goal is to produce front-end compatible classes to handle monetary values, similar to those supported in a Go Money library.
I would like to work on this issue, however, I am new to the level of engineering (virtual machine, assembly code) that this effort would likely entail. I have more experience as an implementor of existing Rust libraries and this would be my first Rust open source contribution.
Would anyone in the be interested in mentoring/pairing on this effort with me?
Thanks! Marianne (Rust Discord @nini_raviolette)
@ImUrX
I have a lot of interwined enums, and enums cant have methods for wasm_bindgen, so this for simplifying a lot of utils would be awesome
Technically speaking, methods are just function that get called in a weird way (there are no methods in Haskell, only functions, even for "traits"). But it was wasm_bindgen decision to convert Rust impl/trait functions in Rust to methods in JavaScript.
It's been 4 years since this issue. Would be great to be able to use wasm_bindgen with impl+trait.
I assume this isn't being worked on anywhere?
This might also be related to this discussion: https://github.com/rustwasm/wasm-bindgen/discussions/3254