Skip to content

Commit e7d743e

Browse files
committed
Split krate into MVC modules
There is still more work to do to extract model logic from some of the controller endpoints, however I'm focusing on getting things moved around in bulk first, and then focus on extracting logic when practical.
1 parent d9fd8b4 commit e7d743e

26 files changed

+228
-197
lines changed

src/controllers/helpers/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
use conduit::Response;
2+
use util::{json_response, CargoResult};
3+
14
pub mod pagination;
25

36
pub use self::pagination::Paginate;
7+
8+
pub fn ok_true() -> CargoResult<Response> {
9+
#[derive(Serialize)]
10+
struct R {
11+
ok: bool,
12+
}
13+
14+
Ok(json_response(&R { ok: true }))
15+
}

src/krate/downloads.rs renamed to src/controllers/krate/downloads.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,13 @@
44
//! download counts are located in `krate::downloads`.
55
66
use std::cmp;
7-
8-
use conduit::{Request, Response};
9-
use conduit_router::RequestParams;
10-
use diesel::prelude::*;
11-
12-
use db::RequestTransaction;
13-
use util::{CargoResult, RequestUtils};
7+
use controllers::prelude::*;
148

159
use views::EncodableVersionDownload;
1610
use models::{Crate, Version, VersionDownload};
17-
use schema::*;
11+
use schema::version_downloads;
1812

19-
use super::to_char;
13+
use models::krate::to_char;
2014

2115
/// Handles the `GET /crates/:crate_id/downloads` route.
2216
pub fn downloads(req: &mut Request) -> CargoResult<Response> {

src/krate/follow.rs renamed to src/controllers/krate/follow.rs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
//! Endpoints for managing a per user list of followed crates
22
3-
use conduit::{Request, Response};
4-
use conduit_router::RequestParams;
53
use diesel::associations::Identifiable;
6-
use diesel::prelude::*;
74
use diesel;
85

9-
use db::RequestTransaction;
10-
use user::RequestUser;
11-
use util::{CargoResult, RequestUtils};
12-
6+
use controllers::prelude::*;
137
use models::{Crate, Follow};
148
use schema::*;
159

@@ -32,23 +26,17 @@ pub fn follow(req: &mut Request) -> CargoResult<Response> {
3226
.values(&follow)
3327
.on_conflict_do_nothing()
3428
.execute(&*conn)?;
35-
#[derive(Serialize)]
36-
struct R {
37-
ok: bool,
38-
}
39-
Ok(req.json(&R { ok: true }))
29+
30+
ok_true()
4031
}
4132

4233
/// Handles the `DELETE /crates/:crate_id/follow` route.
4334
pub fn unfollow(req: &mut Request) -> CargoResult<Response> {
4435
let follow = follow_target(req)?;
4536
let conn = req.db_conn()?;
4637
diesel::delete(&follow).execute(&*conn)?;
47-
#[derive(Serialize)]
48-
struct R {
49-
ok: bool,
50-
}
51-
Ok(req.json(&R { ok: true }))
38+
39+
ok_true()
5240
}
5341

5442
/// Handles the `GET /crates/:crate_id/following` route.
@@ -58,6 +46,7 @@ pub fn following(req: &mut Request) -> CargoResult<Response> {
5846
let follow = follow_target(req)?;
5947
let conn = req.db_conn()?;
6048
let following = diesel::select(exists(follows::table.find(follow.id()))).get_result(&*conn)?;
49+
6150
#[derive(Serialize)]
6251
struct R {
6352
following: bool,

src/krate/metadata.rs renamed to src/controllers/krate/metadata.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,15 @@
44
//! index or cached metadata which was extracted (client side) from the
55
//! `Cargo.toml` file.
66
7-
use conduit::{Request, Response};
8-
use conduit_router::RequestParams;
9-
use diesel::prelude::*;
10-
117
use app::RequestApp;
12-
use db::RequestTransaction;
13-
use util::{human, CargoResult, RequestUtils};
148

9+
use controllers::prelude::*;
1510
use views::{EncodableCategory, EncodableCrate, EncodableDependency, EncodableKeyword,
1611
EncodableVersion};
1712
use models::{Category, Crate, CrateCategory, CrateDownload, CrateKeyword, Keyword, Version};
1813
use schema::*;
1914

20-
use super::ALL_COLUMNS;
15+
use models::krate::ALL_COLUMNS;
2116

2217
/// Handles the `GET /summary` route.
2318
pub fn summary(req: &mut Request) -> CargoResult<Response> {
@@ -142,7 +137,8 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
142137

143138
#[derive(Serialize)]
144139
struct R {
145-
#[serde(rename = "crate")] krate: EncodableCrate,
140+
#[serde(rename = "crate")]
141+
krate: EncodableCrate,
146142
versions: Vec<EncodableVersion>,
147143
keywords: Vec<EncodableKeyword>,
148144
categories: Vec<EncodableCategory>,

src/controllers/krate/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub mod search;
2+
pub mod publish;
3+
pub mod owners;
4+
pub mod follow;
5+
pub mod downloads;
6+
pub mod metadata;

src/krate/owners.rs renamed to src/controllers/krate/owners.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
//! All routes related to managing owners of a crate
22
3-
use conduit::{Request, Response};
4-
use conduit_router::RequestParams;
5-
use diesel::prelude::*;
63
use serde_json;
74

8-
use app::RequestApp;
9-
use db::RequestTransaction;
105
use owner::rights;
11-
use user::RequestUser;
12-
use util::{human, CargoResult, RequestUtils};
136

7+
use controllers::prelude::*;
148
use views::EncodableOwner;
159
use models::{Crate, Owner, Rights, Team, User};
1610

src/krate/publish.rs renamed to src/controllers/krate/publish.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,18 @@ use std::cmp;
44
use std::collections::HashMap;
55
use std::sync::Arc;
66

7-
use conduit::{Request, Response};
8-
use diesel::prelude::*;
97
use hex::ToHex;
108
use serde_json;
119

12-
use app::RequestApp;
13-
use db::RequestTransaction;
1410
use dependency;
1511
use git;
1612
use owner::rights;
1713
use render;
18-
use user::RequestUser;
1914
use util::{read_fill, read_le_u32};
20-
use util::{human, internal, CargoResult, ChainError, RequestUtils};
15+
use util::{internal, ChainError};
2116

22-
use views::EncodableCrate;
23-
use views::EncodableCrateUpload;
17+
use controllers::prelude::*;
18+
use views::{EncodableCrate, EncodableCrateUpload};
2419
use models::{Badge, Category, Keyword, NewCrate, NewVersion, Rights, User};
2520

2621
/// Handles the `PUT /crates/new` route.
@@ -177,7 +172,8 @@ pub fn publish(req: &mut Request) -> CargoResult<Response> {
177172

178173
#[derive(Serialize)]
179174
struct R<'a> {
180-
#[serde(rename = "crate")] krate: EncodableCrate,
175+
#[serde(rename = "crate")]
176+
krate: EncodableCrate,
181177
warnings: Warnings<'a>,
182178
}
183179
Ok(req.json(&R {

src/krate/search.rs renamed to src/controllers/krate/search.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
//! Endpoint for searching and discovery functionality
22
3-
use conduit::{Request, Response};
4-
use diesel::prelude::*;
53
use diesel_full_text_search::*;
64

7-
use db::RequestTransaction;
85
use controllers::helpers::Paginate;
9-
use user::RequestUser;
10-
use util::{CargoResult, RequestUtils};
11-
6+
use controllers::prelude::*;
127
use views::EncodableCrate;
138
use models::{Badge, Crate, OwnerKind, Version};
149
use schema::*;
1510

16-
use super::{canon_crate_name, ALL_COLUMNS};
11+
use models::krate::{canon_crate_name, ALL_COLUMNS};
1712

1813
/// Handles the `GET /crates` route.
1914
/// Returns a list of crates. Called in a variety of scenarios in the

src/controllers/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
mod prelude {
44
pub use diesel::prelude::*;
5+
pub use super::helpers::ok_true;
56

7+
pub use app::RequestApp;
68
pub use conduit::{Request, Response};
79
pub use conduit_router::RequestParams;
810
pub use db::RequestTransaction;
9-
pub use util::{CargoResult, RequestUtils};
11+
pub use user::RequestUser;
12+
pub use util::{human, CargoResult, RequestUtils};
1013
}
1114

1215
pub mod helpers;
1316

1417
pub mod category;
1518
pub mod keyword;
19+
pub mod krate;

src/crate_owner_invitation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ pub struct EncodableCrateOwnerInvitation {
6262
pub invited_by_username: String,
6363
pub crate_name: String,
6464
pub crate_id: i32,
65-
#[serde(with = "::util::rfc3339")] pub created_at: NaiveDateTime,
65+
#[serde(with = "::util::rfc3339")]
66+
pub created_at: NaiveDateTime,
6667
}
6768

6869
/// Handles the `GET /me/crate_owner_invitations` route.

src/dependency.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ pub struct Dependency {
2828

2929
#[derive(Debug, QueryableByName)]
3030
pub struct ReverseDependency {
31-
#[diesel(embed)] dependency: Dependency,
32-
#[sql_type = "::diesel::sql_types::Integer"] crate_downloads: i32,
31+
#[diesel(embed)]
32+
dependency: Dependency,
33+
#[sql_type = "::diesel::sql_types::Integer"]
34+
crate_downloads: i32,
3335
#[sql_type = "::diesel::sql_types::Text"]
3436
#[column_name = "crate_name"]
3537
name: String,

src/lib.rs

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ pub mod download;
7474
pub mod git;
7575
pub mod github;
7676
pub mod http;
77-
pub mod krate;
7877
pub mod owner;
7978
pub mod render;
8079
pub mod schema;
@@ -91,7 +90,6 @@ pub mod models;
9190
pub mod views;
9291

9392
mod local_upload;
94-
mod with_count;
9593

9694
/// Used for setting different values depending on whether the app is being run in production,
9795
/// in development, or for testing.
@@ -130,13 +128,22 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
130128
let mut api_router = RouteBuilder::new();
131129

132130
// Route used by both `cargo search` and the frontend
133-
api_router.get("/crates", C(krate::search::search));
131+
api_router.get("/crates", C(controllers::krate::search::search));
134132

135133
// Routes used by `cargo`
136-
api_router.put("/crates/new", C(krate::publish::publish));
137-
api_router.get("/crates/:crate_id/owners", C(krate::owners::owners));
138-
api_router.put("/crates/:crate_id/owners", C(krate::owners::add_owners));
139-
api_router.delete("/crates/:crate_id/owners", C(krate::owners::remove_owners));
134+
api_router.put("/crates/new", C(controllers::krate::publish::publish));
135+
api_router.get(
136+
"/crates/:crate_id/owners",
137+
C(controllers::krate::owners::owners),
138+
);
139+
api_router.put(
140+
"/crates/:crate_id/owners",
141+
C(controllers::krate::owners::add_owners),
142+
);
143+
api_router.delete(
144+
"/crates/:crate_id/owners",
145+
C(controllers::krate::owners::remove_owners),
146+
);
140147
api_router.delete("/crates/:crate_id/:version/yank", C(version::yank::yank));
141148
api_router.put(
142149
"/crates/:crate_id/:version/unyank",
@@ -152,11 +159,11 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
152159
api_router.get("/versions/:version_id", C(version::deprecated::show));
153160

154161
// Routes used by the frontend
155-
api_router.get("/crates/:crate_id", C(krate::metadata::show));
162+
api_router.get("/crates/:crate_id", C(controllers::krate::metadata::show));
156163
api_router.get("/crates/:crate_id/:version", C(version::deprecated::show));
157164
api_router.get(
158165
"/crates/:crate_id/:version/readme",
159-
C(krate::metadata::readme),
166+
C(controllers::krate::metadata::readme),
160167
);
161168
api_router.get(
162169
"/crates/:crate_id/:version/dependencies",
@@ -172,17 +179,35 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
172179
);
173180
api_router.get(
174181
"/crates/:crate_id/downloads",
175-
C(krate::downloads::downloads),
182+
C(controllers::krate::downloads::downloads),
183+
);
184+
api_router.get(
185+
"/crates/:crate_id/versions",
186+
C(controllers::krate::metadata::versions),
187+
);
188+
api_router.put(
189+
"/crates/:crate_id/follow",
190+
C(controllers::krate::follow::follow),
191+
);
192+
api_router.delete(
193+
"/crates/:crate_id/follow",
194+
C(controllers::krate::follow::unfollow),
195+
);
196+
api_router.get(
197+
"/crates/:crate_id/following",
198+
C(controllers::krate::follow::following),
199+
);
200+
api_router.get(
201+
"/crates/:crate_id/owner_team",
202+
C(controllers::krate::owners::owner_team),
203+
);
204+
api_router.get(
205+
"/crates/:crate_id/owner_user",
206+
C(controllers::krate::owners::owner_user),
176207
);
177-
api_router.get("/crates/:crate_id/versions", C(krate::metadata::versions));
178-
api_router.put("/crates/:crate_id/follow", C(krate::follow::follow));
179-
api_router.delete("/crates/:crate_id/follow", C(krate::follow::unfollow));
180-
api_router.get("/crates/:crate_id/following", C(krate::follow::following));
181-
api_router.get("/crates/:crate_id/owner_team", C(krate::owners::owner_team));
182-
api_router.get("/crates/:crate_id/owner_user", C(krate::owners::owner_user));
183208
api_router.get(
184209
"/crates/:crate_id/reverse_dependencies",
185-
C(krate::metadata::reverse_dependencies),
210+
C(controllers::krate::metadata::reverse_dependencies),
186211
);
187212
api_router.get("/keywords", C(controllers::keyword::index));
188213
api_router.get("/keywords/:keyword_id", C(controllers::keyword::show));
@@ -206,7 +231,7 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
206231
"/me/crate_owner_invitations/:crate_id",
207232
C(crate_owner_invitation::handle_invite),
208233
);
209-
api_router.get("/summary", C(krate::metadata::summary));
234+
api_router.get("/summary", C(controllers::krate::metadata::summary));
210235
api_router.put("/confirm/:email_token", C(user::confirm_user_email));
211236
api_router.put("/users/:user_id/resend", C(user::regenerate_token_and_send));
212237
api_router.get("/site_metadata", C(site_metadata::show_deployed_sha));

src/models/follow.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use models::User;
2+
use schema::follows;
3+
4+
#[derive(Insertable, Queryable, Identifiable, Associations, Clone, Copy, Debug)]
5+
#[belongs_to(User)]
6+
#[primary_key(user_id, crate_id)]
7+
#[table_name = "follows"]
8+
pub struct Follow {
9+
pub user_id: i32,
10+
pub crate_id: i32,
11+
}

src/models/helpers/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod with_count;

src/with_count.rs renamed to src/models/helpers/with_count.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
#[derive(QueryableByName)]
1+
#[derive(QueryableByName, Debug)]
22
pub struct WithCount<T> {
3-
#[sql_type = "::diesel::sql_types::BigInt"] total: i64,
4-
#[diesel(embed)] record: T,
3+
#[sql_type = "::diesel::sql_types::BigInt"]
4+
total: i64,
5+
#[diesel(embed)]
6+
record: T,
57
}
68

79
pub trait WithCountExtension<T> {

0 commit comments

Comments
 (0)