Skip to content

web-sys: Bluetooth usability issues #2381

@chrysn

Description

@chrysn

Motivation

I'm porting Bluetooth using code over from Javascript, and am running into a few warts around how web-sys exposes them.

As I'm relatively new to web-sys usage, I don't have a clear plan forward with them, and they may or may not be related; in this issue I'd like to hash out how they are related, and what can reasonably be done within being a -sys crate.

Issues

  • navigator().bluetooth() may fail: Not all browsers have Bluetooth support, and Mozilla probably won't until it has vastly changed.

    Currently this causes a panic at with wasm-bindgen: imported JS function that was not marked as catch threw an error: getObject(...) is undefined; making .bluetooth() fallible may help here.

  • The request_device method is unusable as the default empty argument for options is not accepted, at least by Chrome. It either needs a concrete filter set, or acceptAllDevices set to true, in the options object.

  • Building the actual options object with a filter as a JsObject is comparatively verbose. To express

    navigator.bluetooth.requestDevice({
            filters: [{services: [serviceUuid]}]
            });

    I had to go through a serde object and wrote

    #[derive(serde::Serialize)]
    struct ServiceFilter {
        services: [&'static str; 1]
    }
    let services = [ServiceFilter { services: [UUID_US] }];
    b.request_device_with_options(
        web_sys::RequestDeviceOptions::new().filters(
            &wasm_bindgen::JsValue::from_serde(&services).unwrap()
    )).then([...]

    Making what MDN calls BluetoothScanFilters available in Rust might help, but so would an example of how to do this more in-line in the JsValue documentation. (I'm pretty sure there's a way to write RequestDeviceOptions::new().filters(js! [ {"services": [UUID_US]} ]), I just didn't find it). If that's accessible easily, it may even be worth considering to drop RequestDeviceOptions in favor of going all JavaScript object (given most of the possible options incur going to a JsValue right again), possibly through a TryInto (but that wouldn't be zero-cost; in a regular API one could probably go from accepting RequestDeviceOptions to accepting any Into which RequestDeviceOptions could then implement for compatibility, but a) this is all unstable anyway, and b) given there's codegen involved, such stunts may be hard).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions