3 #[cfg(feature = "suggestions")]
9 /// Produces a string from a given list of possible values which is similar to
10 /// the passed in value `v` with a certain confidence.
11 /// Thus in a list of possible values like ["foo", "bar"], the value "fop" will yield
12 /// `Some("foo")`, whereas "blark" would yield `None`.
13 #[cfg(feature = "suggestions")]
14 #[cfg_attr(feature = "lints", allow(needless_lifetimes))]
15 pub fn did_you_mean
<'a
, T
: ?Sized
, I
>(v
: &str, possible_values
: I
) -> Option
<&'a
str>
16 where T
: AsRef
<str> + 'a
,
17 I
: IntoIterator
<Item
= &'a T
>
20 let mut candidate
: Option
<(f64, &str)> = None
;
21 for pv
in possible_values
{
22 let confidence
= strsim
::jaro_winkler(v
, pv
.as_ref());
23 if confidence
> 0.8 &&
24 (candidate
.is_none() || (candidate
.as_ref().unwrap().0 < confidence
)) {
25 candidate
= Some((confidence
, pv
.as_ref()));
30 Some((_
, candidate
)) => Some(candidate
),
34 #[cfg(not(feature = "suggestions"))]
35 pub fn did_you_mean
<'a
, T
: ?Sized
, I
>(_
: &str, _
: I
) -> Option
<&'a
str>
36 where T
: AsRef
<str> + 'a
,
37 I
: IntoIterator
<Item
= &'a T
>
42 /// Returns a suffix that can be empty, or is the standard 'did you mean' phrase
43 #[cfg_attr(feature = "lints", allow(needless_lifetimes))]
44 pub fn did_you_mean_flag_suffix
<'z
, T
, I
>(arg
: &str, longs
: I
, subcommands
: &'z
[App
])
45 -> (String
, Option
<&'z
str>)
46 where T
: AsRef
<str> + 'z
,
47 I
: IntoIterator
<Item
= &'z T
>
49 match did_you_mean(arg
, longs
) {
51 let suffix
= format
!("\n\tDid you mean {}{}?", Format
::Good("--"), Format
::Good(candidate
));
52 return (suffix
, Some(candidate
))
55 for subcommand
in subcommands
{
56 let opts
= subcommand
.p
.flags
.iter().filter_map(|f
| f
.s
.long
).chain(
57 subcommand
.p
.opts
.iter().filter_map(|o
| o
.s
.long
));
59 if let Some(candidate
) = did_you_mean(arg
, opts
) {
61 "\n\tDid you mean to put '--{}' after the subcommand '{}'?",
63 Format
::Good(candidate
));
64 return (suffix
, Some(candidate
));
69 return (String
::new(), None
)
72 /// Returns a suffix that can be empty, or is the standard 'did you mean' phrase
73 pub fn did_you_mean_value_suffix
<'z
, T
, I
>(arg
: &str, values
: I
) -> (String
, Option
<&'z
str>)
74 where T
: AsRef
<str> + 'z
,
75 I
: IntoIterator
<Item
= &'z T
>
77 match did_you_mean(arg
, values
) {
79 let suffix
= format
!("\n\tDid you mean '{}'?", Format
::Good(candidate
));
80 (suffix
, Some(candidate
))
82 None
=> (String
::new(), None
),
86 #[cfg(all(test, features = "suggestions"))]
91 fn possible_values_match() {
92 let p_vals
= ["test", "possible", "values"];
93 assert_eq
!(did_you_mean("tst", p_vals
.iter()), Some("test"));
97 fn possible_values_nomatch() {
98 let p_vals
= ["test", "possible", "values"];
99 assert
!(did_you_mean("hahaahahah", p_vals
.iter()).is_none());
104 let p_vals
= ["test", "possible", "values"];
105 let suffix
= "\n\tDid you mean \'--test\'?";
106 assert_eq
!(did_you_mean_flag_suffix("tst", p_vals
.iter(), []), (suffix
, Some("test")));
111 let p_vals
= ["test", "possible", "values"];
112 let suffix
= "\n\tDid you mean \'test\'?";
113 assert_eq
!(did_you_mean_value_suffix("tst", p_vals
.iter()), (suffix
, Some("test")));