動的な値も `Did you mean 'hoge'?` したい
clap-rs には、suggestion というユーザーの typo を検知するための feature が実装されています。
しかし、これは Runtime に定まる値に対して、typo を検知できません。
あくまで、事前に定義しておいたオプションリストに対して suggestion を提供しているだけです。
例えば Zellij の v0.21.0 より前のバージョンでは、存在しないセッションに対して attach しようとした時、ただ単にそのセッションが存在しない旨を伝えてくるだけでした。
$ zellij attach organic-snace
No session named "organic-snace" found.
合っていると思いながら、zellij list-sessions
を実行すると、typo していたみたいなことが起こります。
$ zellij list-sessions
organic-snake
black-and-white-thing
draconian-flowers
そういったユースケースのために、suggestion という crate を開発しました。
こちらを使用すると、以下のように Runtime に確定する値リストに対して、suggestion を提供できます。
$ zellij attach organic-snace
No session named "organic-snace" found.
help: Did you mean `organic-snake`?
使い方
使い方は非常にシンプルで、以下のように使用できます。
use suggestion::Suggest;
fn main() {
let input = "instakk";
let list_commands = vec!["update", "install"];
if list_commands.contains(&input) {
return;
}
if let Some(sugg) = list_commands.suggest(input) {
println!("No command named `{}` found.", input);
println!("Did you mean `{}`?", sugg);
}
}
基本的な Primitive Types に対して、Trait を定義しているため、use suggestion::Suggest
とすれば、suggest
メソッドが生えてきます。
例えば、Zellij の場合だと、list-sessions
サブコマンド用の関数が用意されているので、それを併用することで以下のように実装しています。
println!("No session named {:?} found.", name);
if let Some(sugg) = get_sessions().unwrap().suggest(name) {
println!(" help: Did you mean `{}`?", sugg);
}
CLI として使用する
suggestion は、CLI も実装しています。
以下のコマンドでインストールできます。
$ cargo install suggestion
こちらの使い方もシンプルで、最初の引数が typo かもしれない入力で、その後ろの引数全てが suggestion したい値リストとなります。
$ suggest instakk update install
The `instakk` input is similar to `install`.
以下の README.md に詳細が載っているので、興味がある方は見ていただけると幸いです。
suggestion 自体の実装に関して
suggestion 自体の実装に関しても、興味のある方向けに紹介いたします。
lev_distance
Levenshtein distance というアルゴリズムを実装している crate です。
簡単にいうと、文字列の近さを計測するためのアルゴリズムです。
Rust のコンパイラが、typo を検知するために内部的に使用していたソースコードを、一般的な String でも使用できるように改変したものになります。
Rust のコンパイラ専用ということで、実装には Symbol が使用されていますが、それをそのまま切り出すわけにはいかないため、String を使用するように置き換えています。
上記の crate は、Rust のコンパイラとして指定されているライセンスのもとで公開されています。
ありがとうございます。
suggestion
後は、上記の lev_distance
crate を使用して、使用しやすいインターフェースを実装しているだけとなっています。
最後に
suggestion は、CLI アプリケーションを実装しているとどうしてもどこかで欲しくなる機能ですが、実装が面倒だと感じていました。
それを今回 crate にすることで、簡単に再利用できるようにしました。
色々な方が、CLI アプリケーションを実装したことがあると思うので、この crate が役に立てば幸いです。
Author And Source
この問題について(動的な値も `Did you mean 'hoge'?` したい), 我々は、より多くの情報をここで見つけました https://zenn.dev/matken/articles/suggestion-for-dynamic-values著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol