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
を表すGuest
traitはbindings
モジュール直下
-->bindings::exports::docs::calculator::Guest
にはならないのか? -
use
しているrandomインターフェースの中にあるrecordとenumは上記のimportの規則に従っているように見える
どういうこと?
質問してみた
と、いうわけでcargo-componentのissueとして聞いてみました。
メインコミッターであるPeter氏は私のようなドシロウトに非常に丁寧に答えてくれる方で、とてもありがたいです。
彼の回答からわかったのは以下のことでした。
- 基本的にはこのルールはwit-bindgenの仕様に基づくものである
- cargo-componentのマクロはそれに接頭辞として
bindings
をつける - worldから関数が直接exportされる場合には
Guest
traitはbindings
モジュール直下につくられる - worldからinterfaceがexportされる場合には私の推測通り
bindings::exports::パッケージ名::インターフェース名
というモジュール以下にGuest
traitが作られる - worldからimportされるものは推測通り
bindings::パッケージ名::インターフェース名
モジュールになる
これでスッキリしたクリスマスを迎えられそうです!
Discussion