LoginSignup
3
1

More than 1 year has passed since last update.

Rustで一時ディレクトリを扱う

Last updated at Posted at 2023-05-03

現在フリーランスエンジニアとして活動していて、今今携わっている案件ではRustとTauriを使ってExcelファイルを出力するデスクトップアプリを開発しています。

予め環境変数にファイルの出力フォルダを設定することで、Excelファイルの出力機能で出力フォルダを取得しファイルを書き出します。

上記機能の自動テストを実装するために、一時ディレクトリを作成し、出力フォルダに作成したディレクトリを指定しています。一時ディレクトリを作成して指定するのは自動テストが完了したら作成したファイルを削除するためです。

今回Rustで一時ディレクトリを作成するためにtempfileというクレート

と環境変数を設定するためにenvtestkitというクレート

を使用します。

早速、上記クレートを使用したCSVファイルを出力するサンプルコード(&テストコード)の載せます。

Cargo.toml
[dev-dependencies]
envtestkit = "1.1.2"
tempfile = "3.5.0"
Rust
use std::{env, io};
use std::fs::File;
use std::path::PathBuf;

use csv::Writer;

fn write_csv() -> io::Result<()> {
    let export_folder = env::var("EXPORT_FOLDER").map_err(|_| {
        io::Error::new(io::ErrorKind::NotFound, "環境変数 EXPORT_FOLDER が設定されていません。")
    })?;

    // CSVファイルの出力先パスを生成
    let file_path = PathBuf::from(export_folder).join("output.csv");

    // CSVデータの例
    let records = vec![
        vec!["header1", "header2", "header3"],
        vec!["row1_col1", "row1_col2", "row1_col3"],
        vec!["row2_col1", "row2_col2", "row2_col3"],
    ];

    let file = File::create(&file_path)?;
    let mut writer = Writer::from_writer(file);

    for record in records {
        writer.write_record(record)?;
    }

    writer.flush()?;
    Ok(())
}

fn main() -> io::Result<()> {
    // CSVファイルにデータを書き込む
    write_csv()?;

    Ok(())
}

#[cfg(test)]
mod tests {
    use io::prelude::*;
    use std::ffi::OsString;

    use envtestkit::lock::lock_test;
    use envtestkit::set_env;
    use tempfile::tempdir;

    use super::*;

    #[test]
    fn test_should_write_csv_when_export_folder_is_set() -> io::Result<()> {
        // Arrange
        // テストための一時フォルダを作成
        let temp_dir = tempdir()?;
        let _lock = lock_test();
        // 環境変数に作成した一時フォルダのパスを指定
        let _test = set_env(OsString::from("EXPORT_FOLDER"), temp_dir.path().to_str().unwrap());
        let file_path = temp_dir.path().join("output.csv");

        // Act
        write_csv()?;

        // Assert
        let mut file = File::open(&file_path)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        let expected_contents = "header1,header2,header3\nrow1_col1,row1_col2,row1_col3\nrow2_col1,row2_col2,row2_col3\n";
        assert_eq!(contents, expected_contents);

        // Cleanup
        temp_dir.close()?;
        Ok(())
    }
}

上記テストコードを実行すると、/var/folders/sj/gd26nn_j6hs40wglhq7flq9r0000gn/T/.tmp1dapCq/output.csvのように一時ファイルを作成してテストが完了したらファイルを削除します。

以上で自動テストを実行することで無駄にファイルが残ってしまうのを防止できるようになりました。

3
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1