Rust でファイル名の一部を変えたPathBufを作りたい時の方法

今回はタイトルの通り、「Rust でファイル名の一部を変えたPathBufを作りたい時の方法」について備忘を兼ねて書いていきます。

例えばファイルを入力して処理し、それを別のファイル名に保存したい時(例を出すと、"plain.txt"のようなファイルに暗号化をして"plain_encrypted.txt"みたいな名前に変えて保存する、とか)などでパスの一部を変更したい時が意外に手間がかかったので自分なりに辿り着いた書き方を残します(本当はもっと良い書き方がありそうな気がしてますが、これ以上は思いつきませんでした)

下の例では、C:\directory\foobar.txtC:\\directory\\foobar_hoge.txtに変える(ファイル名に_hogeを加える)処理を行っています

use std::path::PathBuf;

fn main() {
    let path: PathBuf = PathBuf::from(r"C:\directory\foobar.txt");
    println!("path {:?}", path); // path: "C:\\directory\\foobar.txt"

    let filename: &std::ffi::OsStr = path.file_stem().unwrap();
    println!("filename: {:?}", filename); // filename: "foobar"

    let extension: &std::ffi::OsStr = path.extension().unwrap();
    println!("extension: {:?}", extension); // extension: "txt"

    let mut filename_after: std::ffi::OsString = filename.to_os_string();
    filename_after.push("_hoge");

    let mut path_after: PathBuf = path.clone();
    path_after.set_file_name(filename_after);
    path_after.set_extension(extension);
    println!("path_after: {:?}", path_after); // path_after: "C:\\directory\\foobar_hoge.txt"

    // string と &str の時みたいに OsString + &OsStr は出来ない
    //let mut test2 = filename.to_os_string() + std::ffi::OsStr::new("test");
}

ファイル名と拡張子をfile_stem()extension()で取り出し、ファイル名の方はpush(_hoge)で文字列を加えています

(上のコメントのコードで書きましたがOsString系は+演算子で文字列を結合することができないみたいです)

その後set_file_name()set_extension()を行いで新しいファイル名に変更します。

set_file_name()はファイル名の部分ではなく拡張子を含んだ部分のようで、set_extension()を書かないとC:\\directory\\foobar_hogeと拡張子無しになってしまいます)


今回は以上です。

きっともっと良い方法がありそうだなぁと思いつつ、それが判明するまでは上のやり方を使っていこうと思います。