Rust + Tauri + TypeScriptで指定した位置の天気と気温を表示するツールを作ってみた

![296434937-e7cef7a5-b2ef-49ef-94d1-73966c94c2b2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139073/d0c126cb-d695-886b-4885-45b4706280be.png) ![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139073/bb3a5478-85ff-ee92-9ab8-4905aa0bbe78.png)
## はじめに
最近、血圧を下げるためによく散歩をするのですが外に出た瞬間に 寒っ！となることがよくありました。部屋に戻ってもう一枚着込む手間が発生していて外の気温を常時表示するツールがあると便利だなと思って、このツールを作ってみました。

以下の人には参考になるかもしれません。
* Rust + Tauri + TypeScript の組み合わせでWindowsのデスクトップアプリケーションを作ってみたい人
* [OpenWeatherMapのAPI](https://openweathermap.org/api)に興味がある人
* 外の気温を表示するツールを探している人

## 事前準備
### インストール
* [Rust](https://www.rust-lang.org/ja/tools/install)をインストール
* [Node.js](https://nodejs.org/en)をインストール
### プロジェクトを作成
>以下の手順でプロジェクトを作成してください

`npm create tauri-app@latest`
? Project name (tauri - app) › temp
? Choose which language to use for your frontend › TypeScript / JavaScript (pnpm, yarn, npm, bun)
? Choose your package manager › npm
? Choose your UI template › Vanilla
? Choose your UI flavor › TypeScript
`cd temp`
`npm install`
`npm run tauri dev`

>Welcome to Tauri!　のウィンドウが表示されると思います。

完成形のプロジェクトは [こちら](https://github.com/8bitTD/temp) に置いておきます。以下躓いたポイントだけ解説します。
## 躓いたポイント

### Rust の関数越しに変数を共有する方法
>[main.rsの.setup内で変数を格納した構造体を登録して](https://github.com/8bitTD/temp/blob/main/src-tauri/src/main.rs#L148)、各関数の引数[state: tauri::State<Mutex<MyApp>>で取り出して取得、編集する](https://github.com/8bitTD/temp/blob/main/src-tauri/src/main.rs#L72)のが一般的みたいです。※非同期(async)の関数だと非対応なので、[引数でうまいことやり繰りする](https://github.com/8bitTD/temp/blob/main/src-tauri/src/main.rs#L78)必要があるみたいです。

### reqwestクレートでOpenWeatherAPIから情報を受け取るときの型指定
>以前はその都度戻り値に合うように構造体を作っていたのですが、[serde_json::Value](https://github.com/8bitTD/temp/blob/main/src-tauri/src/main.rs#L86C14-L86C31)にすることで何でも受け取れる魔法の型になるようです。[その後の取り扱いもjsonっぽく扱えて](https://github.com/8bitTD/temp/blob/main/src-tauri/src/main.rs#L88C1-L88C1)とても便利に思います。以前の自分に教えてあげたかった…orz

### ウィンドウを透明にする

>[tauri.conf.jsonのwindowsのtransparentをtrue](https://github.com/8bitTD/temp/blob/main/src-tauri/tauri.conf.json#L52) にしただけでは透明にならなかったです。[cssのbackground-colorのアルファ部分](https://github.com/8bitTD/temp/blob/main/src/styles.css#L12)も変更しないといけないみたいです。

### スクロールバーを表示させないようにする

> cssで[こんな感じで書く](https://github.com/8bitTD/temp/blob/main/src/styles.css#L1)と表示させないようにできました。

### htmlのlabel部分を白文字＋黒アウトラインにして見やすくする

>cssで[こんな感じに書く](https://github.com/8bitTD/temp/blob/main/src/styles.css#L32)とできました。あまり太くできないみたいです。

### アイコンを変更する

> src-tauri/icons/icon.pngにアイコンを上書きして`npm run tauri icon src-tauri/icons/icon.png`で変更できるみたいです。アイコンが変わらない場合は、src-tauri/targetフォルダを削除して試すと反映されました。

### 緯度、経度の情報を取得する方法

> [GoogleMap](https://www.google.co.jp/maps/) 上で右クリックするとContextMenuの一番上に緯度、経度が表示されます。クリックするとクリップボードにコピーされるみたいです。

### ビルド後にHTMLに遷移できない問題

> [こちら](https://qiita.com/8bitTD/items/0d55645e1c7dbc1a5394) の記事でも書きましたが、[vite.config.tsに遷移する.htmlを登録](https://github.com/8bitTD/temp/blob/main/vite.config.ts#L23)しないといけないみたいです。

### tauri.conf.jsonのidentifierの項目は初期状態(com.tauri.dev)だとbuild時にエラーになる

> 変更するとエラーは出ないので、[適当に変更](https://github.com/8bitTD/temp/blob/main/src-tauri/tauri.conf.json#L28)しております。

## 最後に
年末年始でRust + Tauri + TypeScriptの組み合わせでいくつかツールを作ってみたのですが、かなり色々なものが作れそうな気がしました。

個人的には、Rustでデスクトップアプリケーションを作る場合は、[eframe(egui)](https://crates.io/crates/eframe)と並んで選択肢に入ってくるかなと思いました。