@@ -422,8 +422,9 @@ impl<O: futures::Sink<Response> + Unpin> Service<O> {
422422 * no_sort = false ;
423423 } else {
424424 active_search. sort_by ( |a, b| {
425- fn calculate_weight ( meta : & PluginSearchResult , query : & str ) -> usize {
426- let mut weight = 0 ;
425+ // Weight is calculated between 0.0 and 1.0, with higher values being most similar
426+ fn calculate_weight ( meta : & PluginSearchResult , query : & str ) -> f64 {
427+ let mut weight: f64 = 0.0 ;
427428
428429 let name = meta. name . to_ascii_lowercase ( ) ;
429430 let description = meta. description . to_ascii_lowercase ( ) ;
@@ -433,50 +434,48 @@ impl<O: futures::Sink<Response> + Unpin> Service<O> {
433434 . map ( |exec| exec. to_ascii_lowercase ( ) )
434435 . unwrap_or_default ( ) ;
435436
436- if !name. starts_with ( query) {
437- weight = 1 ;
438-
439- if !name. contains ( query) {
440- weight = strsim:: damerau_levenshtein ( & name, query)
441- . min ( strsim:: damerau_levenshtein ( & description, query) ) ;
442-
443- if let Some ( keywords) = meta. keywords . as_ref ( ) {
444- for keyword in keywords. iter ( ) {
445- let keyword = keyword. to_ascii_lowercase ( ) ;
446- weight = if keyword. starts_with ( query)
447- || keyword. contains ( query)
448- {
449- 1
450- } else {
451- weight. min ( strsim:: damerau_levenshtein ( query, & keyword) + 1 )
452- }
453- }
454- }
437+ for name in name. split_ascii_whitespace ( ) {
438+ if name. starts_with ( query) {
439+ return 1.0 ;
455440 }
456441 }
457442
458443 if exec. contains ( query) {
459- weight = if exec. starts_with ( query) {
460- weight . min ( 2 )
444+ if exec. starts_with ( query) {
445+ return 1.0 ;
461446 } else {
462- weight. min ( strsim:: damerau_levenshtein ( query, & exec) )
447+ weight = strsim:: jaro_winkler ( query, & exec) - 0.1 ;
463448 }
464449 }
465450
466451 weight
452+ . max ( strsim:: jaro_winkler ( & name, query) )
453+ . max ( strsim:: jaro_winkler ( & description, query) - 0.1 )
454+ . max ( match meta. keywords . as_ref ( ) {
455+ Some ( keywords) => keywords
456+ . iter ( )
457+ . flat_map ( |word| word. split_ascii_whitespace ( ) )
458+ . fold ( 0.0 , |acc, keyword| {
459+ let keyword = keyword. to_ascii_lowercase ( ) ;
460+ acc. max ( strsim:: jaro_winkler ( query, & keyword) - 0.1 )
461+ } ) ,
462+ None => 0.0 ,
463+ } )
467464 }
468465
469466 let a_weight = calculate_weight ( & a. 1 , query) ;
470467 let b_weight = calculate_weight ( & b. 1 , query) ;
471468
472- match a_weight. cmp ( & b_weight) {
473- Ordering :: Equal => {
469+ match a_weight. partial_cmp ( & b_weight) {
470+ Some ( Ordering :: Equal ) => {
474471 let a_len = a. 1 . name . len ( ) ;
475472 let b_len = b. 1 . name . len ( ) ;
476473
477474 a_len. cmp ( & b_len)
478475 }
479- other => other,
476+ Some ( Ordering :: Less ) => Ordering :: Greater ,
477+ Some ( Ordering :: Greater ) => Ordering :: Less ,
478+ None => Ordering :: Greater ,
480479 }
481480 } ) ;
482481
0 commit comments