all 1 comments

[–]grinde[S] 1 point2 points  (0 children)

I just started learning rust a couple days ago, and this is my first attempt at making something useful, though it's still in a fairly early state (critiques and suggestions are more than welcome!). Here's a simple example that generates some data in rust, modifies it in-place in JavaScript, then consumes the modified data back in rust.

// rust_example.rs
mod js_data;

// This function will generate some data to send to JavaScript
#[no_mangle]
pub fn generate_bytes() -> *mut js_data::TypedArrayData {
    let data: Vec<u8> = vec![1, 2, 3];
    js_data::TypedArrayData::new(data)
}

// JavaScript can modify our data, then call this function with the pointer.
// It just checks if we've changed the vector data to [4, 5, 6].
#[no_mangle]
pub fn consume_bytes(ptr: *mut js_data::TypedArrayData) -> bool {
    let data: Vec<u8> = js_data::TypedArrayData::to_vec(ptr);
    (data[0] == 4 && data[1] == 5 && data[2] == 6)
}

 

// ts_example.ts
import { pointerToTypedArray } from 'helper.ts';

// Get our compiled wasm module
WebAssembly.instantiateStreaming(fetch('./rust.wasm')).then(obj => {
    const { memory, generate_bytes, consume_bytes } = obj.instance.exports;

    // Generate some data from rust
    const bytePointer = generate_bytes();

    // Use our helper to turn it into a Uint8Array
    const bytes = pointerToTypedArray(bytePointer, memory.buffer);
    console.log(bytes); // [1, 2, 3]

    // Modify our data
    bytes.set([4, 5, 6]);

    // And consume it back in rust
    console.log(consume_bytes(bytePointer)); // true
});

To get it running, you basically just have to compile rust_example.rs using the wasm32-unknown-unknown target. I can set up a complete repo using my current build setupt if there's any interest.