Skip to main content

Annotation | Rust

  • Annotation | Rust

Wasm-Bindgen

O atributo #[wasm_bindgen] em Rust é usado em conjunto com o crate wasm-bindgen, que facilita a interação entre Rust e JavaScript ao trabalhar com WebAssembly. Ele permite que funções, estruturas, ou tipos definidos em Rust sejam expostos ao JavaScript e vice-versa.

Como funciona #[wasm_bindgen]

O #[wasm_bindgen] serve como uma ponte entre o ambiente WebAssembly gerado pelo Rust e o JavaScript, fornecendo bindings para que ambos os ambientes possam interagir facilmente.


Configuração no Cargo.toml

Primeiro, o crate wasm-bindgen precisa ser adicionado ao projeto:

[dependencies]
wasm-bindgen = "0.2"

Exemplos de Uso do #[wasm_bindgen]

1. Exportando Funções para JavaScript

Você pode marcar funções com #[wasm_bindgen] para torná-las disponíveis para o JavaScript.

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn saudacao(nome: &str) -> String {
format!("Olá, {}!", nome)
}

No lado do JavaScript:

import init, { saudacao } from './meu_modulo_wasm.js';

async function run() {
await init();
console.log(saudacao("Mundo")); // "Olá, Mundo!"
}
run();
  • A função saudacao será compilada para WebAssembly e poderá ser chamada diretamente do JavaScript.

2. Interagindo com o DOM

Você pode usar o #[wasm_bindgen] para acessar APIs do JavaScript, como manipular o DOM.

use wasm_bindgen::prelude::*;
use web_sys::console;

#[wasm_bindgen]
pub fn log_mensagem(mensagem: &str) {
console::log_1(&mensagem.into());
}

No lado do JavaScript:

import init, { log_mensagem } from './meu_modulo_wasm.js';

async function run() {
await init();
log_mensagem("Mensagem enviada do WebAssembly!");
}
run();
  • Aqui, a função log_mensagem usa o módulo web-sys para acessar o console do navegador diretamente.

3. Exportando Estruturas para JavaScript

Estruturas e métodos também podem ser expostos ao JavaScript.

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub struct Retangulo {
largura: u32,
altura: u32,
}

#[wasm_bindgen]
impl Retangulo {
#[wasm_bindgen(constructor)]
pub fn new(largura: u32, altura: u32) -> Retangulo {
Retangulo { largura, altura }
}

pub fn area(&self) -> u32 {
self.largura * self.altura
}
}

No lado do JavaScript:

import init, { Retangulo } from './meu_modulo_wasm.js';

async function run() {
await init();
const ret = new Retangulo(10, 5);
console.log(`Área do retângulo: ${ret.area()}`); // "Área do retângulo: 50"
}
run();

4. Chamando JavaScript a partir do Rust

Além de expor funções Rust para JavaScript, o #[wasm_bindgen] também permite que você chame funções JavaScript a partir do Rust.

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}

#[wasm_bindgen]
pub fn saudacao_rust() {
log("Olá do Rust!");
}
  • Aqui, a função log do JavaScript (em console.log) é chamada diretamente do Rust.

Características do #[wasm_bindgen]

  1. Exposição de Rust ao JavaScript:

    • Funções, structs, e métodos podem ser usados em JavaScript.
    • Estruturas como #[wasm_bindgen] tornam essas entidades interoperáveis.
  2. Interoperabilidade JavaScript → Rust:

    • É possível importar funções e objetos JavaScript para usá-los dentro do Rust.
  3. Suporte para web-sys e js-sys:

    • web-sys: Para interagir com APIs do navegador (DOM, Web APIs, etc.).
    • js-sys: Para trabalhar com objetos nativos do JavaScript.
  4. Facilidade de uso com wasm-pack:

    • O wasm-pack é frequentemente usado junto com wasm-bindgen para compilar e empacotar o código WebAssembly.