Rust SDK

0.4 NEW — пишем балансер на Rust, собираем cargo build --release --target wasm32-wasip1.

Установка тулчейна

rustup target add wasm32-wasip1
# wasm32-wasi и wasm32-wasip1 совместимы; reactor mode поддерживается обоими

Минимальный плагин

wasm_modules/hello-rs/Cargo.toml:

[package]
name = "hello-rs"
version = "0.0.1"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
lampac-sdk = { path = "../../wasm_sdk/rust" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[profile.release]
opt-level = "z"
lto = true
strip = true

wasm_modules/hello-rs/src/lib.rs:

use lampac_sdk::{handle_export, Invocation, Response};
use serde::Serialize;

handle_export!(handle_impl);

#[derive(Serialize)]
struct Item { name: String }

#[derive(Serialize)]
struct Movie {
    #[serde(rename = "type")]
    kind: &'static str,
    data: Vec<Item>,
}

fn handle_impl(inv: Invocation) -> Response {
    lampac_sdk::info(&format!("got request, path={}", inv.path));
    let q = inv.query.get("q").cloned().unwrap_or_default();
    Response::json(Movie {
        kind: "movie",
        data: vec![Item { name: format!("Hello, {}", q) }],
    })
}

wasm_modules/hello-rs/manifest.json:

{
  "id": "hello_rs",
  "name": "Hello (Rust)",
  "version": "0.1.0",
  "target": "server",
  "language": "rust",
  "abi_version": 1
}

Сборка:

cargo build --release --target wasm32-wasip1
cp target/wasm32-wasip1/release/hello_rs.wasm plugin.wasm

(или просто нажми Build в Browser Studio — оно само положит plugin.wasm рядом с manifest.json).

Что есть в SDK

wasm_sdk/rust/src/lib.rs:

Лог

lampac_sdk::debug("…");
lampac_sdk::info("…");
lampac_sdk::warn("…");
lampac_sdk::error("…");

HTTP

let resp = lampac_sdk::http_get("https://api.example.com/v1/x", None);
// resp.status, resp.headers, resp.body (Vec<u8>), resp.error

Proxy URL

let url = lampac_sdk::proxy_url(
    "https://cdn.example.com/movie.m3u8",
    Some("hello_rs"),
    None,
);

Кеш

lampac_sdk::cache_set("user:42", b"value", 60);
let v: Option<Vec<u8>> = lampac_sdk::cache_get("user:42");

Макрос handle_export!

Регистрирует ваш fn(inv: Invocation) -> Response как WASM-экспорт handle. Внутри обрабатывает alloc, JSON-парсинг и упаковку pack(ptr, len).

Размер

Rust в release + lto = true + opt-level = "z" даёт ~80–150 КБ для плагина уровня echo — заметно меньше, чем TinyGo.

Client target на Rust

Используйте модуль lampac_sdk::client:

use lampac_sdk::client;

#[no_mangle]
pub extern "C" fn on_load() {
    if client::storage_get("seen") == "1" { return; }
    client::noty("Привет от Rust 👋");
    client::storage_set("seen", "1");
}

Все API (storage_get/set, noty, activity_push, emit_event, info/warn/error) — те же, что в TinyGo SDK.

Подводные камни

  • wasm32-wasip1 vs wasm32-wasi — обе работают. Wazero понимает обе вариации snapshot_preview1.
  • При panic! в Rust плагин выгрузится; крэш-дамп будет, но следующая Invoke создаст fresh runtime.
  • serde_json тянет довольно много — если хочется бинарник <50 КБ, разбирай JSON вручную или используй nanoserde.

Полный пример

См. wasm_modules/echo (TinyGo, но логика идентична) — порт на Rust занимает примерно столько же строк.