既定のジャーナル ファイルを使用してタスクを格納する
一部のコマンドライン アプリケーションでは、ドットファイルや構成ファイルなどのユーザー所有のファイルをホーム ディレクトリに配置するのが一般的です。 そのため、既定のジャーナル ファイルもそこに配置することをお勧めします。
ホーム ディレクトリはユーザーのオペレーティング システムによって異なるため、ディレクトリを判断するために home
というサードパーティ製クレートを利用します。
まず、それを Cargo.toml
ファイルに追加します。
[dependencies]
home = "0.5" # <--- Add `home` to our project dependencies.
serde_json = "1.0"
structopt = "0.3"
[dependencies.chrono]
features = ["serde"]
version = "0.4"
[dependencies.serde]
features = ["derive"]
version = "1.0"
これで、home::home_dir()
関数を使用するように main.rs
ファイルを更新できるようになりました。 この関数により、ユーザーのホーム ディレクトリが検索され、CommandLineArgs
型の journal_file
フィールドと同じように、Option<PathBuf>
型で返されます。
// ...
use std::path::PathBuf;
fn find_default_journal_file() -> Option<PathBuf> {
home::home_dir().map(|mut path| {
path.push(".rusty-journal.json");
path
})
}
fn main() {
let CommandLineArgs {
action,
journal_file,
} = CommandLineArgs::from_args();
let journal_file = journal_file
.or_else(find_default_journal_file)
.expect("Failed to find journal file.");
// ...
}
ここでは find_default_journal_file
という新しい関数を作成しました。 入力引数を受け取らず、Option<PathBuf>
が返されます。
この関数内では、既定のジャーナル ファイルの完全なパスを作成する処理が試行されています。 パスを作成するために、home::home_dir
関数の出力から Option
型を取得し、文字列 ".rusty-journal.json"
をパスにプッシュする匿名関数を使用して、その map
メソッドを呼び出しています。 home::home_dir
の出力が None
の場合、map
は Some
バリアントでのみ機能するため、アクションは実行されません。
次に、main
関数で、元の値が None
の場合にのみ、find_default_journal_file
の呼び出しで更新されるように、journal_file
変数を "シャドウ" します。 .or_else
メソッドでは、map
メソッドと逆の処理を行います。バリアントが None
の場合にのみ保持する関数が呼び出されます。
ユーザーが対象のジャーナル ファイルを指定しておらず、find_default_journal_file
によって適切なファイルが見つけられない場合、ジャーナル ファイルなしでは何も実行できないため、プログラムはパニックに陥ります。