cargo-componentによって生成されるbindingsのモジュールネーミングルール
cargo-component is 何?
cargo-componentはWASM Component Model仕様に準拠したWASMをビルドするためのツールです。Rustで最も基本的なツールであるCargoのサブコマンドという形で実装されているのでCargoに慣れた人にとっては学習コストを低く抑えられることが特徴です。
※WASM Compoinet Modelは現在進行系で策定が進んでいるWASMの仕様で、こちらの記事でオーバービューを紹介しているので良かったら参照してください。
bindingsの生成
bindingsはcargo_component_bindings::generateマクロによってWITファイルの情報を元に生成されます。以下のコードはcomponent-modelのチュートリアルからの抜粋です。
これらのbindingsから始まるモジュールに関連するコードはマクロが生成したもので、開発者としてはGuest traitや、Op列挙型のコードは書いていません。
use bindings::exports::docs::calculator::calculate::{Guest, Op};
use bindings::docs::calculator::add::add;
生成結果から推測される規則
calculatorコンポーネントは以下のWITで定義されています。
package docs:calculator@0.1.0;
interface calculate {
enum op {
add,
}
eval-expression: func(op: op, x: u32, y: u32) -> u32;
}
interface add {
add: func(a: u32, b: u32) -> u32;
}
world calculator {
export calculate;
import add;
}
ここから以下の推測ができます。
use bindings::exports::docs::calculator::calculate::{Guest, Op};
| module name | 意味 |
|---|---|
| bindings::exports | exportされるものにつく接頭辞 |
| ::docs::calculator | パッケージ名 |
| ::calculate | インターフェース名 |
- exportするinterfaceは常に
Guestという名前のtraitとしてbindingが生成されるようです - OpはWITに定義されているenum opがRustの列挙型としてbindingが生成されています
use bindings::docs::calculator::add::add;
| module name | 意味 |
|---|---|
| bindings | importされるものはexportsを含まない |
| ::docs::calculator | パッケージ名 |
| ::add | インターフェース名 |
最後のaddはinterface addの中にあるfunc addですね。
そうはならないケースがある
チュートリアルから逸脱して自分でWITを書いてみました。
チュートリアルのケースではworldがimport/exportするのはinterfaceでしたが、上記の例ではfuncをexportしています。
このWITを元に生成されたbindingsは以下のとおりです。
- exportされた
func randを表すGuesttraitはbindingsモジュール直下
-->bindings::exports::docs::calculator::Guestにはならないのか? -
useしているrandomインターフェースの中にあるrecordとenumは上記のimportの規則に従っているように見える
どういうこと?
質問してみた
と、いうわけでcargo-componentのissueとして聞いてみました。
メインコミッターであるPeter氏は私のようなドシロウトに非常に丁寧に答えてくれる方で、とてもありがたいです。
彼の回答からわかったのは以下のことでした。
- 基本的にはこのルールはwit-bindgenの仕様に基づくものである
- cargo-componentのマクロはそれに接頭辞として
bindingsをつける - worldから関数が直接exportされる場合には
Guesttraitはbindingsモジュール直下につくられる - worldからinterfaceがexportされる場合には私の推測通り
bindings::exports::パッケージ名::インターフェース名というモジュール以下にGuesttraitが作られる - worldからimportされるものは推測通り
bindings::パッケージ名::インターフェース名モジュールになる
これでスッキリしたクリスマスを迎えられそうです!
Discussion