TauriとLeptosで作るデスクトップアプリ(3)バックエンドを呼び出す
はじめに
TauriとLeptosでデスクトップアプリを作っていきます。今回は、LeptosフロントエンドからTauriバックエンドのコマンドを呼び出します。あわせて、デバッグ用にフロントエンドのコンソールにログを表示できるようにします。
関連記事
環境
- Windows 11 Home
- Rust 1.80
- Tauri 2.0.0-rc
- Leptos 0.7.0-beta
依存パッケージを追加する
- ロギングを行う
Tauriバックエンド側では、標準出力はそのままcargo tauri dev
を実行したターミナルに表示されます。Leptosフロントエンド側では、ソースコード内でprintln!()
としても、どこにも表示されません。開発者ツールのコンソールでログを確認できるようにlog
とconsole_log
を追加します。
- Tarui APIをRustフロントエンドで扱う
Rustフロントエンド側でTauri APIにバインディングするためにtauri-sys
を追加します。同時にシリアライズするためにserde
を追加します。
上記2つをあわせて、./apps/src-ui/Cargo.toml
の[dependencies]
を以下のように更新します。
[dependencies]
# 略
log = "0.4.22"
console_log = "1.0.0"
serde = { version = "1", features = ["derive"] }
[dependencies.tauri-sys]
git = "https://github.com/JonasKruckenberg/tauri-sys"
branch = "v2"
features = ["all"]
あいさつコンポーネントを作成する
Tauriのcreate-tauri-app
でも自動で作られる「あいさつ」コンポーネントを作成します。LeptosフロントエンドからTauriバックエンドにString
を送信し、それを加工してTauriバックエンドからLeptosフロントエンドにString
を返信します。
Leptosフロントエンドクレート./apps/src-ui
内のcomponents
モジュールにgreet
サブモジュールを作ります。ディレクトリ構成は以下のとおりです。
tauri-leptos-example
├─ apps/
│ ├─ src-tauri/
│ └─ src-ui/
│ ├─ src/
│ │ ├─ components/
│ │ │ ├─ counter.rs
│ │ │ ├─ greet.rs
│ │ │ └─ mod.rs
│ │ ├─ app.rs
│ │ ├─ lib.rs
: : └─ main.rs
mod.rs
にgreet
サブモジュールの宣言を追加します。
pub mod counter;
pub mod greet;
greet.rs
にあいさつコンポーネントを実装します。
use leptos::prelude::*;
use serde::Serialize;
use thaw::{Button, ButtonAppearance, Input, Tag};
#[derive(Serialize)]
struct GreetArgs {
name: String,
}
#[component]
pub fn Greet() -> impl IntoView {
let name = RwSignal::new(String::new());
let greet_msg = RwSignal::new(String::new());
let on_click = move |_| {
leptos::spawn::spawn_local(async move {
let name = name.get_untracked();
log::info!("invoke: {name}");
let args = GreetArgs { name };
let msg: String = tauri_sys::core::invoke("greet", args).await;
greet_msg.set(msg);
})
};
view! {
<div>
<Input placeholder="Enter a name..." value=name />
<Button appearance=ButtonAppearance::Primary on_click>
"Greet"
</Button>
<Tag>{greet_msg}</Tag>
</div>
}
}
on_click
関数の中でlog::info!("invoke: {name}");
としています。これで、開発者ツールのコンソールにログが表示されます。tauri_sys
を使うと、Tauriバックエンドのコマンド呼び出しがinvoke()
関数で簡単にできます。view!
マクロの<Button>
コンポーネントでは、on_click
属性が変数と同名なので、短縮表記をしています。また、ボタンのスタイルをappearance
属性で指定しています。
以下、LeptosフロントエンドのRustソースコードを変更します。
use leptos::prelude::*;
use thaw::ConfigProvider;
use crate::components::counter::SimpleCounter;
use crate::components::greet::Greet;
#[component]
pub fn App() -> impl IntoView {
view! {
<ConfigProvider>
<SimpleCounter initial_value=0 step=1 />
<Greet />
</ConfigProvider>
}
}
use app::App;
use leptos::prelude::*;
mod app;
pub mod components;
pub fn run() {
console_log::init().expect("error initializing logger");
console_error_panic_hook::set_once();
mount_to_body(App)
}
lib.rs
では、console_log::init()
でログレベルをINFOに変更しています。
バックエンドでコマンドを用意する
Tauriバックエンドクレート./apps/src-tauri
内でRustソースコードを実装します。ディレクトリ構成は以下のとおりです。
tauri-leptos-example
├─ apps/
│ ├─ src-tauri/
│ │ ├─ src/
│ │ │ ├─ commands.rs
│ │ │ ├─ lib.rs
│ │ : └─ main.rs
: └─ src-ui/
commands.rs
にコマンドを書きます。今回はString
を受け取って、String
を返す単純な関数です。引数の名前name
は、Leptosフロントエンドで用意した構造体GreetArgs
のフィード名に一致する必要があります。
#[tauri::command]
pub fn greet(name: String) -> String {
println!("invoked: {name}");
format!("Hello, {name}!")
}
lib.rs
でコマンドを実装した関数をハンドラに登録します。
mod commands;
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![commands::greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
プロジェクトを実行します。
> cargo tauri dev
期待どおりの動作が確認できました。
コマンド呼び出しのテスト行う
TODO
サンプルコード
今回作成したプロジェクトは以下からダウンロード可能です。
Discussion