rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript
https://rustwasm.github.io/docs/wasm-bindgen/
Apache License 2.0
7.82k stars 1.08k forks source link

Combine different methods to one javascript function/method to implement overloading. #1139

Open dtysky opened 5 years ago

dtysky commented 5 years ago

Hi, in javascript/typescript, we always define some functions or methods which have different behaviors depends on arguments, etc.:

export default class SName {
  public equalsTo(name: string): boolean;
  public equalsTo(name: SName): boolean;
  public equalsTo(name: string | SName): boolean {
    if (isSName(name)) {
      return this._index === name._index;
    }

    if (!SName.TABLE[name]) {
      return false;
    }

    return SName.TABLE[name] === this._index;
  }
}

This feature is named 'overloading' in some languages and it in javascript is more flexible, but as we known, rust does not support it, so can we use macro to implement it ? Maybe it can like this:

#[wasm_bindgen]
pub struct SName {
  isSName: bool,
  name: str
}

impl SName {
  #[wasm_bindgen(method, js_name="equalsTo", overloading: "name.isSName === false")]
  pub fn equals_to_str(&mut self, name: str) -> bool {
    ......
  }

  #[wasm_bindgen(method, js_name="equalsTo", overloading: "name.isSName === true")]
  pub fn equals_to_sname(&mut self, name: SName) -> bool {
    ......
  }
}

to:

export default class SName {
  public equalsTo(name) {
    if (name.isSName === true) {
      ......
    } else if (name.isSName === false) {
      ......
    }
  }
}
export default class SName {
    isSName: boolean;
    equalsTo(name: string): boolean;
    equalsTo(name: SName): boolean;
}

With features 'overloading', 'optional arguments'(#1129) and 'getter/setter' (#222 ), we can built more powerful and flexible systems, and these features can just be implemented in javascript files and d.ts files. In current time, I can write my own js and ts files to do these, but an automatic implementation is awesome !

Thanks !

alexcrichton commented 5 years ago

Thanks for the report! Would it be possible to define these preflight checks in Rust itself? That way you could take something like a &JsValue and then inspect it to figure out which implementation to delegate to?