シンプルなディレクトリ単位のバックアップツールを作った。
.tar.gz 形式でバックアップするGitHub の Releases から最新版をダウンロードできる。
ぼく個人としては、 主にゲームデータのバックアップ・リストアの用途に使う予定なので、
という2点を主軸に実装してある。
最近 Rust が楽しい、何か1つ作ろう、というのが始まり。
という流れでバックアップツールにした。
また、「クリーンアーキテクチャ、 勉強したり小さく実践したりはしたけど、1からちゃんとやったことないな」 という気持ちがあり、せっかくなのでそれを意識した設計にしてみた。
キレイな設計かどうかは自信ないけど、依存の方向は1方向になっているハズ。
UseCase / Adapter を介して機能を使うデザインのおかげで、 各プレゼンテーション層 (GUI, TUI, Command) の実装は比較的楽だった。
Service を切り替えれば zip などにも対応できる(面倒だからやらないけど)。
Rust で書いた。
Cargo の workspace 機能を使い、 コア部分(ドメイン周りや Infra など)とプレゼンテーション部分で crate を分割した。
lib crate も細かく分割できて、だいぶ開発しやすくて良かった。
反面、 crates.io へ公開するのが難しくなった。
今回は Command としても実装していたし、
サーバで使うときに cargo install で使えたら便利だったんだけど、
最終的には断念した。
具体的には、 Workspace 内の各 lib crate への依存を以下のように記述した場合、 crates.io 上でそれが解決できないため、 publish 時にエラーになる模様。
[workspace.dependencies]
dirback = { path = "crates/lib/dirback" }
jsonfile = { path = "crates/lib/jsonfile" }
mktemp = { path = "crates/lib/mktemp" }
targz = { path = "crates/lib/targz" }
これに対応するには、各 lib crate をそれぞれ crates.io へ公開する必要がある。
各 lib crate を dirback_xxx という名前にして公開することも考えたけど、
面倒になったので中止した。
TUI は Ratatui.rs を使った。
簡単に TUI アプリの実装を開始できて、視覚的にも楽しい。
ただ、複雑な UI のものを作ろうとしたら、 GUI まわりの設計をしっかりしないと厳しそうだった。
GUI は、
の構成にした。
Tauri はネイティブの WebView を使用するので、 Web フレームワークは大体なんでも使える。
各コンテンツ (html,js,css など) の WebView への配布はアプリが行う。
いわゆる埋め込みという形になるので、React や Vue よりは、Svelte や Solidjs のほうが相性は良さそう。
今回はデスクトップ向けだけだし、機能的にも複雑なことはしなかったので、特に躓く点もなく開発できた。
作ってから2週間くらい経ってこれを書いた。 ので、細部を忘れつつある。
個人的にけっこう便利に使ってる。
ちなみに、ロゴ画像は、はじめ ChatGPT に作って貰おうとした。 けど、あんまり良い出力にできなかった。 結局 Inkscake で D の文字を作って Canva で適当なディレクトリ画像と重ねた。
プロンプト力が求められる……。