Запуск Rust на Wippy
Запуск Rust на Wippy
Заголовок раздела «Запуск Rust на Wippy»Сборка Rust WebAssembly-компонента и его запуск как функций, CLI-команд и HTTP-эндпоинтов.
Что мы создаем
Заголовок раздела «Что мы создаем»Rust-компонент с четырьмя экспортируемыми функциями:
- greet - Принимает имя, возвращает приветствие
- add - Складывает два целых числа
- fibonacci - Вычисляет n-е число Фибоначчи
- list-files - Выводит список файлов в смонтированной директории
Мы представим их как вызываемые функции, CLI-команду и HTTP-эндпоинт.
Предварительные требования
Заголовок раздела «Предварительные требования»- Rust toolchain с целевой платформой
wasm32-wasip1 - cargo-component
rustup target add wasm32-wasip1cargo install cargo-componentСтруктура проекта
Заголовок раздела «Структура проекта»rust-wasm-demo/├── demo/ # Rust component│ ├── Cargo.toml│ ├── wit/│ │ └── world.wit # WIT interface│ └── src/│ └── lib.rs # Implementation└── app/ # Wippy application ├── wippy.lock └── src/ ├── _index.yaml # Infrastructure └── demo/ ├── _index.yaml # CLI processes └── wasm/ ├── _index.yaml # WASM entries └── demo_component.wasm # Compiled binaryШаг 1: Создание WIT-интерфейса
Заголовок раздела «Шаг 1: Создание WIT-интерфейса»WIT (WebAssembly Interface Types) определяет контракт между хостом и гостем:
Создайте demo/wit/world.wit:
package component:demo;
world demo { export greet: func(name: string) -> string; export add: func(a: s32, b: s32) -> s32; export fibonacci: func(n: u32) -> u64; export list-files: func(path: string) -> string;}Каждый экспорт становится функцией, которую Wippy может вызвать.
Шаг 2: Реализация на Rust
Заголовок раздела «Шаг 2: Реализация на Rust»Создайте demo/Cargo.toml:
[package]name = "demo"version = "0.1.0"edition = "2024"
[dependencies]wit-bindgen-rt = { version = "0.44.0", features = ["bitflags"] }
[lib]crate-type = ["cdylib"]
[profile.release]opt-level = "s"lto = true
[package.metadata.component]package = "component:demo"Создайте demo/src/lib.rs:
#[allow(warnings)]mod bindings;
use bindings::Guest;
struct Component;
impl Guest for Component { fn greet(name: String) -> String { format!("Hello, {}!", name) }
fn add(a: i32, b: i32) -> i32 { a + b }
fn fibonacci(n: u32) -> u64 { if n <= 1 { return n as u64; } let (mut a, mut b) = (0u64, 1u64); for _ in 2..=n { let next = a + b; a = b; b = next; } b }
fn list_files(path: String) -> String { let mut result = String::new(); match std::fs::read_dir(&path) { Ok(entries) => { for entry in entries { match entry { Ok(e) => { let name = e.file_name().to_string_lossy().to_string(); let meta = e.metadata(); let (kind, size) = match meta { Ok(m) => { let kind = if m.is_dir() { "dir" } else { "file" }; (kind, m.len()) } Err(_) => ("?", 0), }; let line = format!("{:<6} {:>8} {}", kind, size, name); println!("{}", line); result.push_str(&line); result.push('\n'); } Err(e) => { let line = format!("error: {}", e); eprintln!("{}", line); result.push_str(&line); result.push('\n'); } } } } Err(e) => { let line = format!("cannot read {}: {}", path, e); eprintln!("{}", line); result.push_str(&line); result.push('\n'); } } result }}
bindings::export!(Component with_types_in bindings);Модуль bindings генерируется cargo-component из WIT-определения.
Шаг 3: Сборка компонента
Заголовок раздела «Шаг 3: Сборка компонента»cd democargo component build --releaseРезультат — target/wasm32-wasip1/release/demo.wasm. Скопируйте его в приложение Wippy:
mkdir -p ../app/src/demo/wasmcp target/wasm32-wasip1/release/demo.wasm ../app/src/demo/wasm/demo_component.wasmПолучите SHA-256 хеш для проверки целостности:
sha256sum ../app/src/demo/wasm/demo_component.wasmШаг 4: Приложение Wippy
Заголовок раздела «Шаг 4: Приложение Wippy»Инфраструктура
Заголовок раздела «Инфраструктура»Создайте app/src/_index.yaml:
version: "1.0"namespace: demo
entries: - name: gateway kind: http.service meta: comment: HTTP server addr: ":8090" lifecycle: auto_start: true
- name: api kind: http.router meta: comment: Public API router server: demo:gateway prefix: /
- name: processes kind: process.host lifecycle: auto_start: true
- name: terminal kind: terminal.host lifecycle: auto_start: trueФункции WASM
Заголовок раздела «Функции WASM»Создайте app/src/demo/wasm/_index.yaml:
version: "1.0"namespace: demo.wasm
entries: - name: assets kind: fs.directory meta: comment: Filesystem with WASM binaries directory: ./src/demo/wasm
- name: greet_function kind: function.wasm meta: comment: Greet function via payload transport fs: demo.wasm:assets path: /demo_component.wasm hash: sha256:YOUR_HASH_HERE method: greet pool: type: inline
- name: add_function kind: function.wasm meta: comment: Add function via payload transport fs: demo.wasm:assets path: /demo_component.wasm hash: sha256:YOUR_HASH_HERE method: add pool: type: inline
- name: fibonacci_function kind: function.wasm meta: comment: Fibonacci function via payload transport fs: demo.wasm:assets path: /demo_component.wasm hash: sha256:YOUR_HASH_HERE method: fibonacci pool: type: inlineКлючевые моменты:
- Одна запись
fs.directoryпредоставляет WASM-бинарник - Несколько функций ссылаются на один бинарник с разными значениями
method - Поле
hashпроверяет целостность бинарника при загрузке - Пул
inlineсоздает новый экземпляр на каждый вызов
Функции с WASI
Заголовок раздела «Функции с WASI»Функция list-files обращается к файловой системе, поэтому ей нужны WASI-импорты:
- name: list_files_function kind: function.wasm meta: comment: Filesystem listing with WASI mounts fs: demo.wasm:assets path: /demo_component.wasm hash: sha256:YOUR_HASH_HERE method: list-files imports: - wasi:cli - wasi:io - wasi:clocks - wasi:filesystem wasi: mounts: - fs: demo.wasm:assets guest: /data pool: type: inlineСекция wasi.mounts связывает запись файловой системы Wippy с путем в госте. Внутри WASM-модуля /data указывает на директорию demo.wasm:assets.
CLI-команды
Заголовок раздела «CLI-команды»Создайте app/src/demo/_index.yaml:
version: "1.0"namespace: demo.cli
entries: - name: greet kind: process.wasm meta: comment: Greet someone via WASM command: name: greet short: Greet someone via WASM fs: demo.wasm:assets path: /demo_component.wasm hash: sha256:YOUR_HASH_HERE method: greet
- name: ls kind: process.wasm meta: comment: List files from mounted WASI filesystem command: name: ls short: List files from mounted directory fs: demo.wasm:assets path: /demo_component.wasm hash: sha256:YOUR_HASH_HERE method: list-files imports: - wasi:cli - wasi:io - wasi:clocks - wasi:filesystem wasi: mounts: - fs: demo.wasm:assets guest: /dataБлок meta.command регистрирует процесс как именованную CLI-команду. Команда greet не требует WASI-импортов, так как работает только со строками. Команда ls требует доступ к файловой системе.
HTTP-эндпоинт
Заголовок раздела «HTTP-эндпоинт»Добавьте в app/src/demo/wasm/_index.yaml:
- name: http_greet kind: function.wasm meta: comment: Greet exposed via wasi-http transport fs: demo.wasm:assets path: /demo_component.wasm hash: sha256:YOUR_HASH_HERE method: greet transport: wasi-http pool: type: inline
- name: http_greet_endpoint kind: http.endpoint meta: comment: HTTP POST endpoint for WASM greet router: demo:api method: POST path: /greet func: http_greetТранспорт wasi-http преобразует контекст HTTP-запроса/ответа в аргументы и результаты WASM.
Шаг 5: Инициализация и запуск
Заголовок раздела «Шаг 5: Инициализация и запуск»cd appwippy initЗапуск CLI-команд
Заголовок раздела «Запуск CLI-команд»# List available commandswippy run listAvailable commands: greet Greet someone via WASM ls List files from mounted directory# Run greetwippy run greet# Run ls to list mounted directorywippy run lsЗапуск как сервис
Заголовок раздела «Запуск как сервис»wippy runЭто запускает HTTP-сервер на порту 8090. Проверка эндпоинта:
curl -X POST http://localhost:8090/greetВызов из Lua
Заголовок раздела «Вызов из Lua»Функции WASM вызываются так же, как Lua-функции:
local funcs = require("funcs")
local greeting, err = funcs.call("demo.wasm:greet_function", "World")-- greeting: "Hello, World!"
local sum, err = funcs.call("demo.wasm:add_function", 6, 7)-- sum: 13
local fib, err = funcs.call("demo.wasm:fibonacci_function", 10)-- fib: 55Следующие шаги
Заголовок раздела «Следующие шаги»- Обзор WASM - Обзор среды выполнения WebAssembly
- Функции WASM - Справочник по конфигурации функций
- Процессы WASM - Справочник по конфигурации процессов
- Хост-функции - Доступные WASI-импорты
- CLI-справочник - Документация CLI-команд