Show HN: Flutterを使ったRust GUIライブラリ
(cjycode.com)- RustでGUIプログラムを作りたい開発者向けに、Rustの状態・ロジックはそのまま維持しつつ、Flutter UIを組み合わせる方法を提案
- Flutterの成熟したクロスプラットフォームSDKとウィジェットのエコシステム、ピクセル単位の制御、hot reloadによってUIの反復作業を高速化
- 100%純粋なRustのアプローチではないが、HTML/CSS/SlintやマクロベースのDSLのようにUIレイヤーを分離する既存のRust UIの折衷案と似ている
flutter_rust_bridgeは任意の型、&mut、async、traits、results、closure、lifetimesなどを自動変換し、RustとFlutterの間のブリッジとなる- カウンターアプリとtodo-listアプリの例で構成を確認でき、全コードは
flutter_rust_bridgeリポジトリのサンプルディレクトリにある
Rust GUIにFlutterを組み合わせる方法
- RustはStackOverflowとGitHubの基準で8年にわたり「最も望まれるプログラミング言語」に選ばれており、RustでGUIプログラムを作りたいという需要が大きい
- 提案されている方法は、Flutterとflutter_rust_bridgeを使ってRustプログラムにGUIを組み込むもの
- 自分で動かすにはGitHubリポジトリやデモフォルダを利用できる
Flutterを使う理由
- FlutterはStackOverflow基準で「最も人気のあるクロスプラットフォームモバイルSDK」に選ばれており、多くの開発者やブランドが利用している
- 豊富なウィジェットのエコシステムにより、必要なUI機能を実装しやすい
- confettiアニメーションのようなパッケージも存在する
- 多様なウィジェットや機能、ピクセル単位の柔軟な制御を提供する
- hot reloadはUI調整が多い開発工程で反復速度を高める
- コード変更後も状態を失わず、ほぼ即座に更新されたUIを確認できる
- 再コンパイル待ちの時間を減らせる
- 同じコードベースをAndroid、iOSだけでなくLinux、MacOS、Windows、Webでも実行できる
純粋なRustではないという折衷
- このアプローチは100%純粋なRustではない
- Rustが状態とロジックを担当し、FlutterがUIを担当する構成である
- マクロで作ったカスタムDSL、HTML/CSS/Slintのような別言語を使うRust UI方式と似ている
- このような分離は関心の分離に合っており、他の事例でも採用されている方式である
- FlutterはRustを理解していれば学びやすいとされる
- Webプラットフォームには一部批判もあり、静的なWebページよりもGoogle EarthやRiveアニメーションエディタのような「アプリ」形態により適しているように見える
- Flutterにはボイラープレートやスキャフォールドコードが多い
- 小規模プロジェクトでは通常それらのファイルを変更しないため、ないものに近いと見なせる
- 大規模プロジェクトでは変更可能であることが、そのままカスタマイズ可能であることにつながる
flutter_rust_bridgeがつなぐもの
flutter_rust_bridgeの目標は、RustとFlutterの間をひとつの言語のように自然につなぐこと- さまざまな要素を自動変換する
- 任意の型
&mut- async
- traits
- results
- closure(callback)
- lifetimes
- 「Flutterを使ったRust GUI」は可能なユースケースのひとつである
- 他の利用例としては、Flutterから任意のRustライブラリを使ったり、アルゴリズムのようなコードはRustで書き、それ以外はFlutterで書く方法がある
カウンターアプリの例
- この例はRustとFlutterを統合する複数の方法のひとつである
flutter_rust_bridgeは特定の構成を強制しない汎用ツールなので、Redux風やElm風のアプローチも可能である- Rust側では
#[frb(ui_state)]で状態を定義し、#[frb(ui_mutation)]で変更メソッドを示すRustStateはcount: i32を持つnew()はcountを100で初期化するincrement()はcountを1増やす
#[frb(ui_state)]と#[frb(ui_mutation)]は非常に軽量で、内部に隠れた魔法はなく、コードも10行あまりだという- Flutter UIは宣言的に書かれる
- 現在のカウントを表示する
Text state.incrementを呼び出すTextButton- 2つの要素をカラムにまとめ、paddingを適用する
- 現在のカウントを表示する
- 実行中にUIを修正すると、hot reloadで変更をすぐに確認できる
Todo-listアプリの例
- todo-listアプリは完全性のために用意された選択セクションであり、
flutter_rust_bridgeがサポートできる複数のアプローチのひとつである - Rustの状態にはtodo項目、入力テキスト、フィルター、次のIDが含まれる
items: Vec<Item>input_text: Stringfilter: Filternext_id: i32
Itemはid、content、completedを持つFilterはAll、Active、Completedを持つ- 状態変更の動作は
#[frb(ui_mutation)]の下に実装されるadd()は現在の入力テキストで項目を追加し、入力を空にするremove(id)はそのIDの項目を削除するtoggle(id)は完了状態を反転する
- ビジネスロジックは
filtered_items()とFilter::check()で構成されるAllはすべての項目を通すActiveは未完了の項目だけを通すCompletedは完了済みの項目だけを通す
- Flutter UIではテキストフィールド、リストビュー、フィルターボタンのrowをカラムに配置する
SyncTextFieldは入力変更と送信をRustの状態変更に接続する- 各todo項目はチェックボックス、テキスト、削除ボタンで構成される
コードの場所と実行
- 全コードはflutter_rust_bridgeリポジトリにある
frb_example/rust_ui_counterfrb_example/rust_ui_todo_list
- その大半はFlutterの機能によって生じる自動生成のボイラープレートファイルである
- 重要なファイルは
src/app.rsとui/lib/main.dartである - デモの実行は
uiディレクトリで次のコマンドを実行するflutter_rust_bridge_codegen generate && flutter run
まだコメントはありません。