Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leverage WebIDL to generate API wrappers #4

Open
casey opened this issue Apr 26, 2017 · 13 comments
Open

Leverage WebIDL to generate API wrappers #4

casey opened this issue Apr 26, 2017 · 13 comments

Comments

@casey
Copy link
Contributor

casey commented Apr 26, 2017

Not sure this is already on your radar, but as webassembly moves forward it might be worth looking at autogenerating rust interfaces based on WebIDL specs:

https://github.com/heycam/webidl

This document contains some interesting notes about IDL + WebAssembly

https://github.com/WebAssembly/design/blob/master/GC.md

Even if the generated rust code isn't particularly idiomatic, it could take care of a lot of tedious FFI work.

@koute
Copy link
Owner

koute commented Apr 26, 2017

This is definitely something I'd like to look into in the future!

Ideally I'd probably envision something like this:
* We autogenerate the vast majority of the API automatically from WebIDL; we keep it private. (Or perhaps have an stdweb-sys crate or something like that; it's hard to tell right now.)
* We reexport parts which feel like idiomatic Rust.
* We write very thin wrappers around parts which are not idiomatic (e.g. removeEventListener).

Right now though I think it's still too early for this, especially since neither webasm is ready for this nor I (we?) haven't fully explored yet what are the tradeoffs when interacting with JavaScript from Rust and in general what's the best way to do it.

@casey
Copy link
Contributor Author

casey commented Apr 27, 2017

I think you're correct about the not-yet-ready part. I've only seen a few tiny examples of Rust / webasm FFI so far, which are mostly hand rolled.

One thing which would help enormously in this effort would be a central repository of WebIDL APIs. It seems that most WebIDL only exists in specs.

@casey
Copy link
Contributor Author

casey commented Apr 28, 2017

Ooooo, jackpot! Looks like there is a directory full of WebIDL files for the browser APIs in the firefox source tree:

https://dxr.mozilla.org/mozilla-central/source/dom/webidl

I'm not sure if these are used directly, or are perhaps simply a reference.

@ghost
Copy link

ghost commented May 24, 2017

Web DOM IDL files and support files copied from Blink : https://github.com/dart-lang/webcore

@koute
Copy link
Owner

koute commented May 24, 2017

Thanks for the links; it'll certainly come in handy once I get to it, although it'll probably take quite a while until I do. (Unless someone else would like to take a stab at this; I guess writing a parser in Rust for the .idl files would be a good first step [so we can generate whatever we need to generate from these in a build.rs].)

@LegNeato
Copy link

LegNeato commented Jul 6, 2017

Servo does some webidl parsing and rust code gen:

https://github.com/servo/servo/tree/master/components/script/dom/bindings/codegen

Repository owner deleted a comment from maciejss Jul 7, 2017
@Herschel
Copy link
Contributor

Herschel commented Oct 17, 2017

I've been playing with this a tiny bit. The webidl crate can successfully parse thorugh all of these IDLs from servo. The Mozilla and Chromium IDLs both use non-standard extensions to the grammar that webidl-rs doesn't support. I've got it parsing in a build.rs, but not really doing much code generation yet.

My first instinct is that generating these in a stdweb-sys submodule/crate is the way to go, as I expect we'll want to re-implement most of the APIs on top of the sys versions. For example, a lot of the JS 'enum'-ish APIs aren't listed as enums in the IDL, and we'd have to manually map these to a Rust enum type, unless we can put this info in the IDL in some way.

(I can't believe that W3C or WHATWG don't just provide a repo of standard IDLs somewhere?!)

@Diggsey
Copy link
Contributor

Diggsey commented Jan 28, 2018

I implemented a fairly powerful WebIDL => stdweb binding generator: brendanzab/gl-rs#447

It is specifically for WebGL at the moment, although I don't imagine it would require too many changes to use with other APIs.

It is able to fully understand WebIDL types and map them onto the best rust interface, taking into account that parameters are typically passed by reference vs return values by move, and it's capable of remapping types, performing custom conversions for specific types, and annotating methods with generic parameters and constraints to allow for more usable APIs.

As an example, it can take these IDL definitions:

typedef unsigned long  GLuint;
typedef ([AllowShared] Float32Array or sequence<GLfloat>) Float32List;
...
void vertexAttrib4fv(GLuint index, Float32List values);

And convert them to this:

pub type GLuint = u32;
pub type Float32List = TypedArray<f32>;
...
pub fn vertex_attrib4fv<'a0, T0>(&self, index: u32, values: T0) where T0: AsTypedArray<'a0, f32> {
    js!( @{self}.vertexAttrib4fv(@{index}, @{unsafe { values.as_typed_array() }}); );
}

@LegNeato
Copy link

There is also https://github.com/kryptan/webinden by @kryptan

@Pauan Pauan mentioned this issue Jul 5, 2018
@Boscop
Copy link

Boscop commented Aug 14, 2018

@Diggsey
Does this also work for callback based APIs like Geolocation?
https://w3c.github.io/geolocation-api/#idl-index
(I really want Geolocation in stdweb/yew..)

Btw, here is how the FFI for the Geolocation API is defined in PureScript:
https://github.com/chexxor/purescript-dom-geolocation/blob/use-aff/src/DOM/HTML/Navigator/Geolocation.purs
https://github.com/chexxor/purescript-dom-geolocation/blob/use-aff/src/DOM/HTML/Navigator/Geolocation.js

@Diggsey
Copy link
Contributor

Diggsey commented Aug 14, 2018

@Boscop not sure until you try it.

@Boscop
Copy link

Boscop commented Aug 14, 2018

@Diggsey Is your Web IDL bindings generator available in its own crate somewhere?

@Diggsey
Copy link
Contributor

Diggsey commented Aug 14, 2018

No, it's just everything in this module right now: https://github.com/brendanzab/gl-rs/tree/master/webgl_generator/webgl_registry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants