データの編集機能の開発も終えたのでファイルからインポート(読み込み)を行えるようにしてみたいと思います。
インポートするファイルの指定方法はコマンドの引数で指定するようにしたいと思います。
引数の処理は何度か使用したclap crateを使用します。
[dependencies]
clap = { version = "4.5.31", features = ["derive"] }
追加した引数の処理部分は下記のようにしました。
引数がある場合は、bin_data.import_from(&path)
でファイルから読み込みを行い、無い場合は0x00で初期化、となります。
// clap v4
use clap::Parser;
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Args {
/// Path to file
file: Option<String>,
}
// main 関数s
fn main() {
.....
// 引数からファイルの読み込み
let args = Args::parse();
match args.file {
Some(path) => {
let bin_data = message.bin_data_mut();
if let Err(e) = bin_data.import_from(&path) {
eprintln!("{e}");
std::process::exit(-1)
}
let current_file = message.current_file_mut().path_mut();
*current_file = path;
}
None => {
let bin_data = message.bin_data_mut();
let mut data: Vec<u8> = Vec::new();
data.push(0x00);
bin_data.push_back(data);
}
}
.....
ファイルをインポートする処理は、
pub(crate) fn import_from(&mut self, path: &String) -> Result<(), std::io::Error> {
let mut file = std::fs::File::open(path)?;
let mut tmp_buf = Vec::new();
let _ = file.read_to_end(&mut tmp_buf)?;
self.buf.clear();
self.push_back(tmp_buf);
Ok(())
}
また、ファイルをインポートした場合は、ウィンドウ枠にファイル名を表示するようにしています。
// 編集対象ファイル
pub(crate) struct CurrentFile {
path: String,
}
// 編集対象ファイル管理
impl CurrentFile {
fn new() -> Self {
let path = String::new();
Self { path }
}
pub(crate) fn path(&self) -> &String {
&self.path
}
pub(crate) fn path_mut(&mut self) -> &mut String {
&mut self.path
}
pub(crate) fn file_name(&self) -> String {
let file_name = std::path::Path::new(&self.path)
.file_name()
.map(|name| name.to_string_lossy().to_string())
// 取得できない場合はフルパスを使う
.unwrap_or_else(|| self.path.to_string());
if file_name.is_empty() {
"no file".to_string()
} else {
file_name
}
}
}
// ファイル名のみを取得してタイトルとする
let file_name = message.current_file().file_name();
let title = Line::from(format!(" {file_name} ").bold()).centered();
TOC
- 準備
- ターミナル入出力を試す
- ターミナル系crateを利用する
- 編集データと表示処理
- 画面制御
- 編集データへの入出力
- その他
GitHubにコードをアップロードしています。
コードのコメントに書かれているfirst_stepなどをcargoコマンドに渡すと実行できます。
# Example
$ cargo run --example first_step