Skip to content

Commit 802f7ec

Browse files
authored
Extract RequestParamExt::param() extension fn (#5801)
This simplifies how we access path parameters and prepares for adding support for `axum`
1 parent 1f6700c commit 802f7ec

16 files changed

+46
-29
lines changed

src/controllers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ mod frontend_prelude {
1010

1111
mod prelude {
1212
pub use super::helpers::ok_true;
13+
pub use super::util::RequestParamExt;
1314
pub use diesel::prelude::*;
1415

1516
pub use conduit::RequestExt;
16-
pub use conduit_router::RequestParams;
1717
pub use http::{header, StatusCode};
1818

1919
pub use super::conduit_axum::conduit_compat;

src/controllers/category.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn index(req: &mut dyn RequestExt) -> EndpointResult {
3434

3535
/// Handles the `GET /categories/:category_id` route.
3636
pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
37-
let slug = &req.params()["category_id"];
37+
let slug = req.param("category_id").unwrap();
3838
let conn = req.app().db_read()?;
3939
let cat: Category = Category::by_slug(slug).first(&*conn)?;
4040
let subcats = cat

src/controllers/crate_owner_invitation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ pub fn handle_invite_with_token(req: &mut dyn RequestExt) -> EndpointResult {
282282
let config = &state.config;
283283
let conn = state.db_write()?;
284284

285-
let req_token = &req.params()["token"];
285+
let req_token = req.param("token").unwrap();
286286

287287
let invitation = CrateOwnerInvitation::find_by_token(req_token, &conn)?;
288288
let crate_id = invitation.crate_id;

src/controllers/krate/downloads.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub fn downloads(req: &mut dyn RequestExt) -> EndpointResult {
1717
use diesel::dsl::*;
1818
use diesel::sql_types::BigInt;
1919

20-
let crate_name = &req.params()["crate_id"];
20+
let crate_name = req.param("crate_id").unwrap();
2121
let conn = req.app().db_read()?;
2222
let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
2323

src/controllers/krate/follow.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn follow_target(
1313
conn: &DieselPooledConn<'_>,
1414
user_id: i32,
1515
) -> AppResult<Follow> {
16-
let crate_name = &req.params()["crate_id"];
16+
let crate_name = req.param("crate_id").unwrap();
1717
let crate_id = Crate::by_name(crate_name)
1818
.select(crates::id)
1919
.first(&**conn)?;

src/controllers/krate/metadata.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ pub fn summary(req: &mut dyn RequestExt) -> EndpointResult {
126126

127127
/// Handles the `GET /crates/:crate_id` route.
128128
pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
129-
let name = &req.params()["crate_id"];
129+
let name = req.param("crate_id").unwrap();
130130
let include = req
131131
.query()
132132
.get("include")
@@ -299,8 +299,8 @@ impl FromStr for ShowIncludeMode {
299299

300300
/// Handles the `GET /crates/:crate_id/:version/readme` route.
301301
pub fn readme(req: &mut dyn RequestExt) -> EndpointResult {
302-
let crate_name = &req.params()["crate_id"];
303-
let version = &req.params()["version"];
302+
let crate_name = req.param("crate_id").unwrap();
303+
let version = req.param("version").unwrap();
304304

305305
let redirect_url = req
306306
.app()
@@ -319,7 +319,7 @@ pub fn readme(req: &mut dyn RequestExt) -> EndpointResult {
319319
// FIXME: Not sure why this is necessary since /crates/:crate_id returns
320320
// this information already, but ember is definitely requesting it
321321
pub fn versions(req: &mut dyn RequestExt) -> EndpointResult {
322-
let crate_name = &req.params()["crate_id"];
322+
let crate_name = req.param("crate_id").unwrap();
323323
let conn = req.app().db_read()?;
324324
let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
325325
let mut versions_and_publishers: Vec<(Version, Option<User>)> = krate
@@ -350,7 +350,7 @@ pub fn reverse_dependencies(req: &mut dyn RequestExt) -> EndpointResult {
350350
use diesel::dsl::any;
351351

352352
let pagination_options = PaginationOptions::builder().gather(req)?;
353-
let name = &req.params()["crate_id"];
353+
let name = req.param("crate_id").unwrap();
354354
let conn = req.app().db_read()?;
355355
let krate: Crate = Crate::by_name(name).first(&*conn)?;
356356
let (rev_deps, total) = krate.reverse_dependencies(&conn, pagination_options)?;

src/controllers/krate/owners.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::views::EncodableOwner;
88

99
/// Handles the `GET /crates/:crate_id/owners` route.
1010
pub fn owners(req: &mut dyn RequestExt) -> EndpointResult {
11-
let crate_name = &req.params()["crate_id"];
11+
let crate_name = req.param("crate_id").unwrap();
1212
let conn = req.app().db_read()?;
1313
let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
1414
let owners = krate
@@ -22,7 +22,7 @@ pub fn owners(req: &mut dyn RequestExt) -> EndpointResult {
2222

2323
/// Handles the `GET /crates/:crate_id/owner_team` route.
2424
pub fn owner_team(req: &mut dyn RequestExt) -> EndpointResult {
25-
let crate_name = &req.params()["crate_id"];
25+
let crate_name = req.param("crate_id").unwrap();
2626
let conn = req.app().db_read()?;
2727
let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
2828
let owners = Team::owning(&krate, &conn)?
@@ -35,7 +35,7 @@ pub fn owner_team(req: &mut dyn RequestExt) -> EndpointResult {
3535

3636
/// Handles the `GET /crates/:crate_id/owner_user` route.
3737
pub fn owner_user(req: &mut dyn RequestExt) -> EndpointResult {
38-
let crate_name = &req.params()["crate_id"];
38+
let crate_name = req.param("crate_id").unwrap();
3939
let conn = req.app().db_read()?;
4040
let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
4141
let owners = User::owning(&krate, &conn)?
@@ -81,7 +81,7 @@ fn parse_owners_request(req: &mut dyn RequestExt) -> AppResult<Vec<String>> {
8181
}
8282

8383
fn modify_owners(req: &mut dyn RequestExt, add: bool) -> EndpointResult {
84-
let crate_name = &req.params()["crate_id"];
84+
let crate_name = req.param("crate_id").unwrap();
8585

8686
let auth = AuthCheck::default()
8787
.with_endpoint_scope(EndpointScope::ChangeOwners)
@@ -90,7 +90,7 @@ fn modify_owners(req: &mut dyn RequestExt, add: bool) -> EndpointResult {
9090

9191
let logins = parse_owners_request(req)?;
9292
let app = req.app();
93-
let crate_name = &req.params()["crate_id"];
93+
let crate_name = req.param("crate_id").unwrap();
9494

9595
let conn = app.db_write()?;
9696
let user = auth.user();

src/controllers/metrics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn prometheus(req: &mut dyn RequestExt) -> EndpointResult {
2424
return Err(Box::new(MetricsDisabled));
2525
}
2626

27-
let metrics = match req.params()["kind"].as_str() {
27+
let metrics = match req.param("kind").unwrap() {
2828
"service" => app.service_metrics.gather(&*app.db_read()?)?,
2929
"instance" => app.instance_metrics.gather(app)?,
3030
_ => return Err(not_found()),

src/controllers/team.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::views::EncodableTeam;
88
pub fn show_team(req: &mut dyn RequestExt) -> EndpointResult {
99
use self::teams::dsl::{login, teams};
1010

11-
let name = &req.params()["team_id"];
11+
let name = req.param("team_id").unwrap();
1212
let conn = req.app().db_read()?;
1313
let team: Team = teams.filter(login.eq(name)).first(&*conn)?;
1414

src/controllers/token.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ pub fn new(req: &mut dyn RequestExt) -> EndpointResult {
8787

8888
/// Handles the `DELETE /me/tokens/:id` route.
8989
pub fn revoke(req: &mut dyn RequestExt) -> EndpointResult {
90-
let id = req.params()["id"]
90+
let id = req
91+
.param("id")
92+
.unwrap()
9193
.parse::<i32>()
9294
.map_err(|e| bad_request(&format!("invalid token id: {e:?}")))?;
9395

src/controllers/user/me.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ pub fn update_user(req: &mut dyn RequestExt) -> EndpointResult {
102102
let mut body = String::new();
103103
req.body().read_to_string(&mut body)?;
104104

105-
let param_user_id = &req.params()["user_id"];
105+
let param_user_id = req.param("user_id").unwrap();
106106

107107
let state = req.app();
108108
let conn = state.db_write()?;
109109
let user = auth.user();
110110

111111
// need to check if current user matches user to be updated
112-
if &user.id.to_string() != param_user_id {
112+
if user.id.to_string() != param_user_id {
113113
return Err(bad_request("current user does not match requested user"));
114114
}
115115

@@ -169,7 +169,7 @@ pub fn confirm_user_email(req: &mut dyn RequestExt) -> EndpointResult {
169169
use diesel::update;
170170

171171
let conn = req.app().db_write()?;
172-
let req_token = &req.params()["email_token"];
172+
let req_token = req.param("email_token").unwrap();
173173

174174
let updated_rows = update(emails::table.filter(emails::token.eq(req_token)))
175175
.set(emails::verified.eq(true))
@@ -187,7 +187,9 @@ pub fn regenerate_token_and_send(req: &mut dyn RequestExt) -> EndpointResult {
187187
use diesel::dsl::sql;
188188
use diesel::update;
189189

190-
let param_user_id = req.params()["user_id"]
190+
let param_user_id = req
191+
.param("user_id")
192+
.unwrap()
191193
.parse::<i32>()
192194
.map_err(|err| err.chain(bad_request("invalid user_id")))?;
193195

src/controllers/user/other.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::views::EncodablePublicUser;
99
pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
1010
use self::users::dsl::{gh_login, id, users};
1111

12-
let name = lower(&req.params()["user_id"]);
12+
let name = lower(req.param("user_id").unwrap());
1313
let conn = req.app().db_read_prefer_primary()?;
1414
let user: User = users
1515
.filter(lower(gh_login).eq(name))
@@ -23,7 +23,9 @@ pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
2323
pub fn stats(req: &mut dyn RequestExt) -> EndpointResult {
2424
use diesel::dsl::sum;
2525

26-
let user_id = &req.params()["user_id"]
26+
let user_id = req
27+
.param("user_id")
28+
.unwrap()
2729
.parse::<i32>()
2830
.map_err(|err| err.chain(bad_request("invalid user_id")))?;
2931
let conn = req.app().db_read_prefer_primary()?;

src/controllers/util.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::prelude::*;
22
use crate::util::errors::{forbidden, internal, AppError, AppResult};
3+
use conduit_router::RequestParams;
34

45
/// The Origin header (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin)
56
/// is sent with CORS requests and POST requests, and indicates where the request comes from.
@@ -22,3 +23,13 @@ pub fn verify_origin(req: &dyn RequestExt) -> AppResult<()> {
2223
}
2324
Ok(())
2425
}
26+
27+
pub trait RequestParamExt<'a> {
28+
fn param(self, key: &str) -> Option<&'a str>;
29+
}
30+
31+
impl<'a> RequestParamExt<'a> for &'a (dyn RequestExt + 'a) {
32+
fn param(self, key: &str) -> Option<&'a str> {
33+
self.params().find(key)
34+
}
35+
}

src/controllers/version.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ fn extract_crate_name_and_semver(req: &dyn RequestExt) -> AppResult<(&str, &str)
2525
}
2626

2727
fn extract_crate_name(req: &dyn RequestExt) -> &str {
28-
&req.params()["crate_id"]
28+
req.param("crate_id").unwrap()
2929
}
3030

3131
fn extract_semver(req: &dyn RequestExt) -> AppResult<&str> {
32-
let semver = &req.params()["version"];
32+
let semver = req.param("version").unwrap();
3333
if semver::Version::parse(semver).is_err() {
3434
return Err(cargo_err(&format_args!("invalid semver: {semver}")));
3535
};

src/controllers/version/deprecated.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub fn index(req: &mut dyn RequestExt) -> EndpointResult {
5252
/// The frontend doesn't appear to hit this endpoint. Instead, the version information appears to
5353
/// be returned by `krate::show`.
5454
pub fn show_by_id(req: &mut dyn RequestExt) -> EndpointResult {
55-
let id = &req.params()["version_id"];
55+
let id = req.param("version_id").unwrap();
5656
let id = id.parse().unwrap_or(0);
5757
let conn = req.app().db_read()?;
5858
let (version, krate, published_by): (Version, Crate, Option<User>) = versions::table

src/controllers/version/downloads.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use chrono::{Duration, NaiveDate, Utc};
1616
pub fn download(req: &mut dyn RequestExt) -> EndpointResult {
1717
let app = req.app();
1818

19-
let mut crate_name = req.params()["crate_id"].clone();
20-
let version = req.params()["version"].as_str();
19+
let mut crate_name = req.param("crate_id").unwrap().to_string();
20+
let version = req.param("version").unwrap();
2121

2222
let mut log_metadata = None;
2323

0 commit comments

Comments
 (0)