Calculator ➕✖️➖➗
2023年5月に開催されたMotoko Bootcamp Day 1のプロジェクトをRust言語で試してみました。
Local Canisterへの配備まで実施した手順を記載します。
1. Rustプロジェクト作成
Rustのプロジェクト「day1」を作成します。cargo newコマンドを--libオプションを付与して実行します。
$ cargo new day1 --lib
$ cd day1生成されたファイルは以下の通りです。
day1
├── Cargo.toml
└── src
└── lib.rs2. Cargo.tomlの編集
(1) IC関連ライブラリ追加
ic-cdkを使用します。最新バージョンでよいかと思いますので、以下のように実行ます。
$ cargo add ic-cdk(2) crate-type設定
Canister上から関数が正しく呼び出させるようcrate-typeをcdylibにします。
[lib]
crate-type = ["cdylib"]3. dfx.jsonの作成
Canisterの定義を行います。
{
"canisters": {
"day1": {
"candid": "./day1.did",
"package": "day1",
"type": "rust"
}
},
"defaults": {
"build": {
"args": "",
"packtool": ""
}
},
"version": 1
}dfx.jsonの記述に関する公式ドキュメントはこちらが参考になります。
4. candidの作成
dfx.jsonの [canisters] > [day1] > [candid]項目に指定したファイルに、Canisterに配置するDappが提供する関数のI/Fを定義します。
Motoko Bootcamp Day1 📺 Interfaceに相当するcandidを用意します。
service : {
add: (float64) -> (float64);
sub: (float64) -> (float64);
mul: (float64) -> (float64);
div: (float64) -> (opt float64);
reset: () -> ();
see: () -> (float64) query;
power: (float64) -> (float64);
sqrt: () -> (float64);
floor: () -> (int);
}参考:Candidリファレンス
5. lib.rsの編集
cargo newコマンドで生成されたlib.rsの中身をクリアして、day1用のプログラムを作成します。
Motoko Bootcamp Day1と同じように、以下の関数を実装します。
add()
sub()
mul()
div()
reset()
see()
power()
sqrt()
floor()
Canister内部で保持するデータは、公式チュートリアル・サンプルにもあるように、「thread_local!」内で管理すると良いようです。
use std::cell::RefCell;
thread_local! {
static COUNTER: RefCell<f64> = RefCell::new(0f64);
}
#[ic_cdk::update]
fn add(x: f64) -> f64 {
COUNTER.with(|counter| {
let mut c = counter.borrow_mut();
*c += x;
*c
})
}
︙6. Unitテスト
Rustではソース内にUnitテストコードを含めて記述することができます。
TODO: 今回の範囲ではロジックにIC色は無いため、UnitテストはLocal canisterに配備せずそのまま実行する方法としましたが、Canisterに配置したテストの方法は未調査。
$ cargo test補足
assertによる一致判定を行う際、assert_eq!(expected, actual)なのか、assert_eq!(actual, expected)なのかは議論がありますが、Rust公式ドキュメントのMacro std::assert_eqのExamplesや、JUnitなどの流れから、前者としています。
7. Local Canisterの起動
Local Canisterを起動します。
--backgroundオプションでサービス常駐でき、--cleanを付与すると真っ新な状態でLocal canisterを起動できます。
$ dfx start --background --clean8. Local Canisterへの配備
$ dfx deployCargo.lockが無い場合
Cargo.lockがディレクトリに存在しない場合、dfx deployがエラーとなります。
その場合、たとえば、以下のように作成するとよいでしょう。
$ cargo generate-lockfile作成資材
.
├── Cargo.lock
├── Cargo.toml
├── day1.did
├── dfx.json
└── src
└── lib.rsCargo.lock
Cargo.toml
day1.did
dfx.json
src/lib.rs
dfx startコマンドを実行すると.dfxディレクトリが作成されます。cargo testコマンドを実行するとtarget/debugディレクトリが作成されます。dfx deployコマンドを実行するとtarget/releaseディレクトリ、およびtarget/wasm32-unknown-unknownが作成されます。
最終更新
役に立ちましたか?