Skip to content

Commit 83e1593

Browse files
Paul Woolcocksgrif
Paul Woolcock
authored andcommitted
Allow multiple keywords in crate search
This commit allows multiple `keyword=` parameters in the querystring to enable searching for all crates under the specified keywords Towards #1461
1 parent b20b7b4 commit 83e1593

File tree

5 files changed

+23
-4
lines changed

5 files changed

+23
-4
lines changed

Cargo.lock

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ tempdir = "0.3.7"
6262
parking_lot = "0.7.1"
6363
jemallocator = { version = "0.1.8", features = ['unprefixed_malloc_on_supported_platforms', 'profiling'] }
6464
jemalloc-ctl = "0.2.0"
65+
collecting-hashmap = "0.1"
6566

6667
lettre = { version = "0.9", git = "https://github.com/lettre/lettre" }
6768
lettre_email = { version = "0.9", git = "https://github.com/lettre/lettre" }

src/controllers.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod prelude {
1212
pub use crate::middleware::current_user::RequestUser;
1313

1414
use std::collections::HashMap;
15+
use collecting_hashmap::CollectingHashMap;
1516
use std::io;
1617

1718
use serde::Serialize;
@@ -21,7 +22,7 @@ mod prelude {
2122
fn redirect(&self, url: String) -> Response;
2223

2324
fn json<T: Serialize>(&self, t: &T) -> Response;
24-
fn query(&self) -> HashMap<String, String>;
25+
fn query(&self) -> CollectingHashMap<String, String>;
2526
fn wants_json(&self) -> bool;
2627
fn pagination(&self, default: usize, max: usize) -> CargoResult<(i64, i64)>;
2728
}
@@ -31,7 +32,7 @@ mod prelude {
3132
crate::util::json_response(t)
3233
}
3334

34-
fn query(&self) -> HashMap<String, String> {
35+
fn query(&self) -> CollectingHashMap<String, String> {
3536
url::form_urlencoded::parse(self.query_string().unwrap_or("").as_bytes())
3637
.map(|(a, b)| (a.into_owned(), b.into_owned()))
3738
.collect()

src/controllers/krate/search.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,17 @@ pub fn search(req: &mut dyn Request) -> CargoResult<Response> {
9999
);
100100
}
101101

102-
if let Some(kw) = params.get("keyword") {
102+
if let Some(kws) = params.get_all("keyword") {
103103
has_filter = true;
104+
105+
use diesel::dsl::any;
106+
let names: Vec<_> = kws.iter().map(|name| name.to_lowercase()).collect();
104107
query = query.filter(
105108
crates::id.eq_any(
106109
crates_keywords::table
107110
.select(crates_keywords::crate_id)
108111
.inner_join(keywords::table)
109-
.filter(crate::lower(keywords::keyword).eq(crate::lower(kw))),
112+
.filter(crate::lower(keywords::keyword).eq(any(names))),
110113
),
111114
);
112115
} else if let Some(letter) = params.get("letter") {

src/tests/krate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ fn index_queries() {
139139
assert_eq!(anon.search("keyword=kw1").crates.len(), 2);
140140
assert_eq!(anon.search("keyword=KW1").crates.len(), 2);
141141
assert_eq!(anon.search("keyword=kw2").crates.len(), 0);
142+
assert_eq!(anon.search("keyword=kw1&keyword=kw3").crates.len(), 3);
142143

143144
assert_eq!(anon.search("q=foo&keyword=kw1").crates.len(), 1);
144145
assert_eq!(anon.search("q=foo2&keyword=kw1").crates.len(), 0);

0 commit comments

Comments
 (0)