rustwebassemblywasm-bindgen

How to use string slices in Rust targeting WebAssembly


I've developped a library in Rust to parse RTF content. I've initially targeted x86 architectures. So I have use lots of string slices (&str) to reference to the original source without copying its content. For instance, a Token looks like :

enum Token<'a> {
    PlainText(&'a str),
    OpeningBracket,
    ClosingBracket,
    ...
}

I want to update my library to also target WebAssembly. I have taken a look into the wasm-bingen crate, an the Rust Wasm book, and it looks like wasm_bindgen doesn't support references nor lifetimes.

Is there an elegant solution for me to adapt my codebase to support WebAssembly without sacrificing the initial performances ?

I have conditional compilation, but I still have the lifetime issue :

#[cfg(not(target_arch = "wasm32"))]
pub type StrRef<'a> = &'a str;
#[cfg(target_arch = "wasm32")]
pub type StrRef = String;

How can I expose this Token enum, for instance, to be used in a JS environement ?


Solution

  • There are more problems here than you've found.

    Given all of these issues, I would recommend that instead of trying to use conditional compilation to adjust type definitions, you create separate types and functions dedicated to providing the JS-compatible API that makes the most sense for JS. Approach this as wrapping your existing library, not as modifying it to be compatible.

    In fact, you should consider making this JS binding wrapper a separate crate that depends on your library. If you insert #[wasm_bindgen] exports in your main Rust library, this means that every Rust-to-WebAssembly build including your library will include all those exports to JS, even if your library is being used solely by other Rust code within that one Wasm module. (This could even cause a name conflict.) Keeping it separate means that the JS exports are only present when they are needed.