Expand description
String-to-command resolution with prefix and ambiguity detection.
The resolver implements a three-phase algorithm:
- Normalize — trim whitespace and lowercase the input.
- Exact match — check the input against every command’s canonical name, aliases, and spellings. Return immediately if exactly one matches.
- Prefix match — check which commands have at least one matchable
string that starts with the normalized input. If exactly one command
matches, return it. If more than one matches, return
ResolveError::Ambiguous. If none match, returnResolveError::Unknown.
This algorithm allows users (and agents) to type unambiguous prefixes like
dep instead of deploy while still producing clear errors when a prefix
is shared by multiple commands.
When a command cannot be found, the resolver also computes up to three
“did you mean?” suggestions based on Levenshtein edit distance (≤ 2) or
substring containment, and attaches them to the ResolveError::Unknown
variant.
§Example
let cmds = vec![
Command::builder("list").alias("ls").build().unwrap(),
Command::builder("log").build().unwrap(),
];
let resolver = Resolver::new(&cmds);
// Exact canonical
assert_eq!(resolver.resolve("list").unwrap().canonical, "list");
// Exact alias
assert_eq!(resolver.resolve("ls").unwrap().canonical, "list");
// Unambiguous prefix
assert_eq!(resolver.resolve("lo").unwrap().canonical, "log");
// Ambiguous prefix — "l" matches both "list" and "log"
assert!(resolver.resolve("l").is_err());
// Near-miss — "lust" is one edit away from "list"
match resolver.resolve("lust") {
Err(ResolveError::Unknown { suggestions, .. }) => {
assert!(suggestions.contains(&"list".to_string()));
}
_ => unreachable!(),
}Structs§
- Resolver
- Resolves a string token to a
Commandin a slice, supporting aliases, spellings, and unambiguous prefix matching.
Enums§
- Resolve
Error - Errors produced by
Resolver::resolve.