treeコマンドをRustで書いた
勉強のためにtreeコマンドをRustで書いたよ
treeコマンドの要旨
treeコマンドはlsコマンドの再帰的な表示を木構造で表したものです。
これはこれまで意識したことはなかったのですが、コードを読んで確かに再帰的な処理で事足りるなと思いました。
prefix
prefixに対して空白などを追加していくことでディレクトリを右にずらしていくことにより、再帰的な深さを表すことができます。
Rustでコマンド自作 Treeコマンド編
作業メモ
- よくわからない。
コマンドラインのパーサを使わない予定だったが、正直面倒なので使ったほうがいいのかもしれない。
- 参考にしているtree-rsはclapを使っている。でもstructoptはclapをラップしている。
- deriveマクロにも対応していてチュートリアルが押しているので、初心者むけなんだろうと考えずに使うことにする。
データを扱うので、構造体にする
- structoptで引数を構造体optにした。
debugマクロを入れることで構造体のprintをできるようにした。
どうやって表示するか
prefix + |---- + filename
ここで、fileがディレクトリだった場合、再帰的にもう一度移動してディレクトリを出力する。
必要な関数
ウォーク関数の詳細
if index == len(filepaths) - 1: print(prefix + "└── " + filepaths[index]) if os.path.isdir(absolute): self.walk(absolute, prefix + " ") else: print(prefix + "├── " + filepaths[index]) if os.path.isdir(absolute): self.walk(absolute, prefix + "│ ")
もし最後ならprefix(初期値"") "└── "
filter_map()
- イテレータの中身を探索するのに便利。勝手にイテレータのindexをジャンプしてくれる。
- https://doc.rust-lang.org/std/iter/struct.FilterMap.html
prefixをString::from("")で作成する
- hello.push('w');で後々伸ばせる。
フルパスではなく、ファイル名を表示する
let filename = path.file_name().unwrap().to_str().unwrap();
ToDoスタック
- [x] 構造体optを作る
- [x] optからpathを表示する
- [x] pathの前にprefix(階層を表す記号)をどうやって挿入するか調べる。
- [x] 再起させずに、まずはファイル名の前にprefixと記号を入れてみる。
- [x] 必要な関数の概要を理解する
- [x] pythonのコードを読んで必要な関数の概要を理解する
- [x] rustのコードを読んで必要な関数の概要を理解する
- [x] vec<>にpathを入れる
- [x] resultをunwrapする
- [x] prefixをString::from("")で作成する
- [x] paths配列の中身をフルパスではなく、ディレクトリorファイル名のみにする。
- [x] 一番うしろを切り取る方法を調べる。
重要だけど今じゃないToDoスタック
- [ ] オプションをパースして取得する
- [ ] .からtreeを始める(treeの根)
参考文献
https://rust-cli.github.io/book/tutorial/cli-args.html https://github.com/kddeisz/tree/blob/master/tree.py https://doc.rust-lang.org/std/path/struct.Path.html https://github.com/sighol/tree-rs https://github.com/alexanderwe/rs-tree