@@ -914,33 +914,39 @@ impl App {
914914 let mut results: Vec < SearchResult > = apps
915915 . par_iter ( )
916916 . filter_map ( |( id, infos) | {
917- let mut best_result : Option < SearchResult > = None ;
917+ let mut best_weight : Option < i64 > = None ;
918918 for AppEntry {
919919 backend_name,
920920 info,
921921 installed,
922922 } in infos. iter ( )
923923 {
924924 if let Some ( weight) = filter_map ( id, info, * installed) {
925- // Skip if best result has lower weight
926- if let Some ( prev_result ) = & best_result {
927- if prev_result . weight < weight {
925+ // Skip if best weight has equal or lower weight
926+ if let Some ( prev_weight ) = best_weight {
927+ if prev_weight <= weight {
928928 continue ;
929929 }
930930 }
931931
932- //TODO: put all infos into search result?
933- // Replace best result
934- best_result = Some ( SearchResult {
935- backend_name,
936- id : id. clone ( ) ,
937- icon_opt : None ,
938- info : info. clone ( ) ,
939- weight,
940- } ) ;
932+ // Replace best weight
933+ best_weight = Some ( weight) ;
941934 }
942935 }
943- best_result
936+ let weight = best_weight?;
937+ // Use first info as it is preferred, even if other ones had a higher weight
938+ let AppEntry {
939+ backend_name,
940+ info,
941+ installed,
942+ } = infos. first ( ) ?;
943+ Some ( SearchResult {
944+ backend_name,
945+ id : id. clone ( ) ,
946+ icon_opt : None ,
947+ info : info. clone ( ) ,
948+ weight,
949+ } )
944950 } )
945951 . collect ( ) ;
946952 results. par_sort_unstable_by ( |a, b| match a. weight . cmp ( & b. weight ) {
@@ -1182,67 +1188,43 @@ impl App {
11821188 async move {
11831189 tokio:: task:: spawn_blocking ( move || {
11841190 let start = Instant :: now ( ) ;
1185- let results =
1186- Self :: generic_search ( & apps, & backends, |_id, info, _installed| {
1187- if !matches ! ( info. kind, AppKind :: DesktopApplication ) {
1188- return None ;
1189- }
1190- //TODO: improve performance
1191- let stats_weight = |weight : i64 | {
1192- //TODO: make sure no overflows
1193- ( weight << 56 ) - ( info. monthly_downloads as i64 )
1194- } ;
1195- //TODO: fuzzy match (nucleus-matcher?)
1196- match regex. find ( & info. name ) {
1197- Some ( mat) => {
1198- if mat. range ( ) . start == 0 {
1199- if mat. range ( ) . end == info. name . len ( ) {
1200- // Name equals search phrase
1201- Some ( stats_weight ( 0 ) )
1202- } else {
1203- // Name starts with search phrase
1204- Some ( stats_weight ( 1 ) )
1205- }
1206- } else {
1207- // Name contains search phrase
1208- Some ( stats_weight ( 2 ) )
1209- }
1191+ let results = Self :: generic_search ( & apps, & backends, |id, info, _installed| {
1192+ if !matches ! ( info. kind, AppKind :: DesktopApplication ) {
1193+ return None ;
1194+ }
1195+ //TODO: improve performance
1196+ let stats_weight = |weight : i64 | -> i64 {
1197+ //TODO: make sure no overflows
1198+ ( weight << 56 ) - ( info. monthly_downloads as i64 )
1199+ } ;
1200+
1201+ //TODO: fuzzy match (nucleus-matcher?)
1202+ let regex_weight = |string : & str , weight : i64 | -> Option < i64 > {
1203+ let mat = regex. find ( string) ?;
1204+ if mat. range ( ) . start == 0 {
1205+ if mat. range ( ) . end == string. len ( ) {
1206+ // String equals search phrase
1207+ Some ( stats_weight ( weight + 0 ) )
1208+ } else {
1209+ // String starts with search phrase
1210+ Some ( stats_weight ( weight + 1 ) )
12101211 }
1211- None => match regex. find ( & info. summary ) {
1212- Some ( mat) => {
1213- if mat. range ( ) . start == 0 {
1214- if mat. range ( ) . end == info. summary . len ( ) {
1215- // Summary equals search phrase
1216- Some ( stats_weight ( 3 ) )
1217- } else {
1218- // Summary starts with search phrase
1219- Some ( stats_weight ( 4 ) )
1220- }
1221- } else {
1222- // Summary contains search phrase
1223- Some ( stats_weight ( 5 ) )
1224- }
1225- }
1226- None => match regex. find ( & info. description ) {
1227- Some ( mat) => {
1228- if mat. range ( ) . start == 0 {
1229- if mat. range ( ) . end == info. summary . len ( ) {
1230- // Description equals search phrase
1231- Some ( stats_weight ( 6 ) )
1232- } else {
1233- // Description starts with search phrase
1234- Some ( stats_weight ( 7 ) )
1235- }
1236- } else {
1237- // Description contains search phrase
1238- Some ( stats_weight ( 8 ) )
1239- }
1240- }
1241- None => None ,
1242- } ,
1243- } ,
1212+ } else {
1213+ // String contains search phrase
1214+ Some ( stats_weight ( weight + 2 ) )
12441215 }
1245- } ) ;
1216+ } ;
1217+ if let Some ( weight) = regex_weight ( & info. name , 0 ) {
1218+ return Some ( weight) ;
1219+ }
1220+ if let Some ( weight) = regex_weight ( & info. summary , 3 ) {
1221+ return Some ( weight) ;
1222+ }
1223+ if let Some ( weight) = regex_weight ( & info. description , 6 ) {
1224+ return Some ( weight) ;
1225+ }
1226+ None
1227+ } ) ;
12461228 let duration = start. elapsed ( ) ;
12471229 log:: info!(
12481230 "searched for {:?} in {:?}, found {} results" ,
@@ -1571,12 +1553,12 @@ impl App {
15711553
15721554 let entry_sort = |a : & AppEntry , b : & AppEntry , id : & AppId | {
15731555 // Sort with installed first
1574- match a . installed . cmp ( & b . installed ) {
1556+ match b . installed . cmp ( & a . installed ) {
15751557 cmp:: Ordering :: Equal => {
15761558 // Sort by highest priority first to lowest priority
15771559 let a_priority = priority ( a. backend_name , & a. info . source_id , id) ;
15781560 let b_priority = priority ( b. backend_name , & b. info . source_id , id) ;
1579- match a_priority . cmp ( & b_priority ) {
1561+ match b_priority . cmp ( & a_priority ) {
15801562 cmp:: Ordering :: Equal => {
15811563 match LANGUAGE_SORTER . compare ( & a. info . source_id , & b. info . source_id ) {
15821564 cmp:: Ordering :: Equal => {
0 commit comments