@@ -52,14 +52,15 @@ where
52
52
T : Iterator < Item = & ' a Symbol > ,
53
53
{
54
54
let max_dist = dist. map_or_else ( || cmp:: max ( lookup. len ( ) , 3 ) / 3 , |d| d) ;
55
+ let name_vec: Vec < & Symbol > = iter_names. collect ( ) ;
55
56
56
- let ( case_insensitive_match, levenstein_match ) = iter_names
57
+ let ( case_insensitive_match, levenshtein_match ) = name_vec . iter ( )
57
58
. filter_map ( |& name| {
58
59
let dist = lev_distance ( lookup, & name. as_str ( ) ) ;
59
60
if dist <= max_dist { Some ( ( name, dist) ) } else { None }
60
61
} )
61
62
// Here we are collecting the next structure:
62
- // (case_insensitive_match, (levenstein_match, levenstein_distance ))
63
+ // (case_insensitive_match, (levenshtein_match, levenshtein_distance ))
63
64
. fold ( ( None , None ) , |result, ( candidate, dist) | {
64
65
(
65
66
if candidate. as_str ( ) . to_uppercase ( ) == lookup. to_uppercase ( ) {
@@ -73,10 +74,32 @@ where
73
74
} ,
74
75
)
75
76
} ) ;
76
-
77
+
78
+ // Priority of matches:
79
+ // 1. Exact case insensitive match
80
+ // 2. Levenshtein distance match
81
+ // 3. Sorted word match
77
82
if let Some ( candidate) = case_insensitive_match {
78
- Some ( candidate) // exact case insensitive match has a higher priority
83
+ Some ( * candidate)
84
+ } else if levenshtein_match. is_some ( ) {
85
+ levenshtein_match. map ( |( candidate, _) | * candidate)
79
86
} else {
80
- levenstein_match . map ( | ( candidate , _ ) | candidate )
87
+ find_match_by_sorted_words ( name_vec , lookup )
81
88
}
82
89
}
90
+
91
+ fn find_match_by_sorted_words < ' a > ( iter_names : Vec < & ' a Symbol > , lookup : & str ) -> Option < Symbol > {
92
+ iter_names. iter ( ) . fold ( None , |result, candidate| {
93
+ if sort_by_words ( & candidate. as_str ( ) ) == sort_by_words ( lookup) {
94
+ Some ( * * candidate)
95
+ } else {
96
+ result
97
+ }
98
+ } )
99
+ }
100
+
101
+ fn sort_by_words ( name : & str ) -> String {
102
+ let mut split_words: Vec < & str > = name. split ( '_' ) . collect ( ) ;
103
+ split_words. sort ( ) ;
104
+ split_words. join ( "_" )
105
+ }
0 commit comments