SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

フロントエンジニアのためのTauri 2.0ではじめるRustプログラミング

Rustを使って「名前を付けて保存」メニューとファイルを保存する機能を実装しよう!

フロントエンジニアのための「Tauri 2.0」ではじめるRustプログラミング 第7回


  • X ポスト
  • このエントリーをはてなブックマークに追加

ファイルにベジェ曲線データを保存する

 最後にフロントエンドから送られたベジェ曲線データをファイルに保存する機能を実装します。「ファイルに名前を付けて保存」するダイアログは、デフォルトではデスクトップフォルダが開かれます。

ダイアログのダジャレ
ダイアログのダジャレ

ベジェ曲線データを名前を付けて保存する

 以下のサンプルコード[3]を追記して、プロジェクトをデバッグビルドして実行したら、何らかの絵を描いて「ファイル」→「名前を付けて保存」メニューを実行してください。すると、次の図のようにファイルダイアログが表示されます。ファイル名を付けて保存すると、引数のベジェ曲線データを「,(コンマ)」区切りで1行の文字列に変換して、テキスト形式でファイルに保存します。

 戻り値の「_saved」変数に最後に保存したファイルのパスが入っており、ファイルを開くダイアログを開くときにそのディレクトリを最初に開きます。

名前を付けて保存ダイアログ
名前を付けて保存ダイアログ
[3] サンプルコード「src-tauri」→「src」→「lib.rs」
// クレート
use tauri::{menu::*, AppHandle, Wry, Error, State, Manager, App, path::BaseDirectory};
use std::fs;
use rfd::FileDialog;
use std::path::Path;
// 読み込み書き込みパス構造体
struct LoadSavePath {
  data_path: String,
  desktop_path: String,
}
impl LoadSavePath {
  fn new(app:&mut App) -> Self {
    let path = Path::new("data");
    let bd = BaseDirectory::Resource;
    let resource_path = app.path()
      .resolve(path,bd)
      .expect("failed to resolve resource");
    let desktop_path = app.path()
      .desktop_dir()
      .expect("failed to resolve resource");
    LoadSavePath {
      data_path: resource_path.display().to_string(),
      desktop_path: desktop_path.display().to_string(),
    }
  }
}
(中略)
// データ保存TAURIコマンド関数
#[tauri::command]
fn save(data: Vec<isize>,loadsave: State<'_, LoadSavePath>) -> String {
  let dir = Path::new(&loadsave.desktop_path);
  let path = FileDialog::new()
    .add_filter("Bezier", &["bezier"])
    .set_directory(dir)
    .save_file();
  if path != None {
    let file_path = path.unwrap();
    let mut arr = Vec::new();
    // データ配列を文字列に
    for d in data { arr.push(d.to_string()); }
    let text = arr.join(",");
    // 文字列の保存
    fs::write(file_path.clone(), text).unwrap();
    file_path.display().to_string()
  } else {
    "".to_string()
  }
}
(後略)

サンプルコードの解説

 LoadSavePath構造体のコンストラクタ「new」メソッドで、デスクトップのパスを「desktop_path」プロパティに代入します。

 TAURIコマンドsave関数でデスクトップのパスを取得して、「名前を付けて保存」ダイアログを開いてファイルを保存する場合、引数の「data」配列の各要素を文字列に変換して「arr」配列に追加します。arr配列を「,」区切りで1行の文字列に繋ぎ(joinメソッド)、「text」変数に代入します。「write」関数でtext変数をファイルに保存します。そのファイル名を戻り値として返します。

 ファイルを保存しない場合は空のファイル名を戻り値として返します。

コラム「ステート機能」

 なぜデスクトップのパスやリソースのパスをわざわざ構造体で持つのか不思議に思った人も少なくないでしょう。それは「App」構造体でアプリの情報をTAURIコマンド関数の中に受け渡すために必要だからです。App構造体のインスタンスが得られなければ、作ったアプリのリソースフォルダのパスが得られないのです。

 「State」のステート機能を使えば、run関数とTAURIコマンド関数の間でデータを受け渡すことができるようになります。例えばプログラミング言語「C/C++」なら「グローバル変数」を使ってできますが、Rustはグローバル変数が使えないため、ステート機能を使います。

おわりに

 今回はプログラミング言語「Rust」で、バックエンドでメニューを追加したり、フロントエンドからバックエンドにお絵描きデータを渡したり、お絵描きデータを保存したりしました。

 これで連載は終了です。Tauri 2.0もRustもまだまだ書き足りないことばかりですが、ここで一旦終わりにしたいと思います。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
フロントエンジニアのためのTauri 2.0ではじめるRustプログラミング連載記事一覧

もっと読む

この記事の著者

大西 武(オオニシ タケシ)

 1975年香川県生まれ。大阪大学経済学部経営学科中退。プログラミング入門書などを30冊以上商業出版する作家。ドコモでグランプリなどコンテストに20回以上入賞するアーティスト。オリジナルの間違い探し「3Dクイズ」がTVで約10回出題。プロフィールサイト:https://profile.vixar.jp

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

CodeZine編集部(コードジンヘンシュウブ)

CodeZineは、株式会社翔泳社が運営するソフトウェア開発者向けのWebメディアです。「デベロッパーの成長と課題解決に貢献するメディア」をコンセプトに、現場で役立つ最新情報を日々お届けします。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/21158 2025/05/12 18:07

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング