Skip to content

Commit 2d82b5a

Browse files
committed
Auto merge of #3124 - Turbo87:encodable, r=pietroalbini
Convert `encodable()` methods to `From` implementations Our JSON `views` and the database `models` are currently tightly coupled through the `encodable()` methods on almost all models. Instead of having the database models depend on the JSON views it would be better to reverse this relationship, so that the database models can live on their own, and only the JSON views are depending on the database models. This would eventually allow us to extract the database models and schema into a dedicated crate, which would then allow us to cut down the dependency tree of some second-level binaries like `monitor` and `background-worker` This PR starts the process of moving away from `encodable()` by implementing the `From` trait for two of our JSON views. This allows us to call `.into()` on the models to automatically convert it to the JSON view form. r? `@pietroalbini`
2 parents c06f929 + 7baa13e commit 2d82b5a

File tree

6 files changed

+36
-34
lines changed

6 files changed

+36
-34
lines changed

src/controllers/category.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub fn index(req: &mut dyn RequestExt) -> EndpointResult {
1818
let conn = req.db_conn()?;
1919
let categories =
2020
Category::toplevel(&conn, sort, i64::from(options.per_page), i64::from(offset))?;
21-
let categories = categories.into_iter().map(Category::encodable).collect();
21+
let categories = categories.into_iter().map(Category::into).collect();
2222

2323
// Query for the total count of categories
2424
let total = Category::count_toplevel(&conn)?;
@@ -47,15 +47,15 @@ pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
4747
let subcats = cat
4848
.subcategories(&conn)?
4949
.into_iter()
50-
.map(Category::encodable)
50+
.map(Category::into)
5151
.collect();
5252
let parents = cat
5353
.parent_categories(&conn)?
5454
.into_iter()
55-
.map(Category::encodable)
55+
.map(Category::into)
5656
.collect();
5757

58-
let cat = cat.encodable();
58+
let cat = EncodableCategory::from(cat);
5959
let cat_with_subcats = EncodableCategoryWithSubcategories {
6060
id: cat.id,
6161
category: cat.category,

src/controllers/krate/metadata.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub fn summary(req: &mut dyn RequestExt) -> EndpointResult {
8585

8686
let popular_categories = Category::toplevel(&conn, "crates", 10, 0)?
8787
.into_iter()
88-
.map(Category::encodable)
88+
.map(Category::into)
8989
.collect();
9090

9191
#[derive(Serialize)]
@@ -179,7 +179,7 @@ pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
179179
.map(|(v, pb, aas)| v.encodable(&krate.name, pb, aas))
180180
.collect(),
181181
keywords: kws.into_iter().map(Keyword::encodable).collect(),
182-
categories: cats.into_iter().map(Category::encodable).collect(),
182+
categories: cats.into_iter().map(Category::into).collect(),
183183
}))
184184
}
185185

src/models/badge.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use std::collections::HashMap;
55

66
use crate::models::Crate;
77
use crate::schema::badges;
8-
use crate::views::EncodableBadge;
98

109
/// A combination of a `Badge` and a crate ID.
1110
///
@@ -108,11 +107,6 @@ impl Queryable<badges::SqlType, Pg> for Badge {
108107
}
109108

110109
impl Badge {
111-
pub fn encodable(self) -> EncodableBadge {
112-
// The serde attributes on Badge ensure it can be deserialized to EncodableBadge
113-
serde_json::from_value(serde_json::to_value(self).unwrap()).unwrap()
114-
}
115-
116110
pub fn update_crate(
117111
conn: &PgConnection,
118112
krate: &Crate,

src/models/category.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use diesel::{self, *};
33

44
use crate::models::Crate;
55
use crate::schema::*;
6-
use crate::views::EncodableCategory;
76

87
#[derive(Clone, Identifiable, Queryable, QueryableByName, Debug)]
98
#[table_name = "categories"]
@@ -57,25 +56,6 @@ impl Category {
5756
categories::table.filter(Self::with_slugs_case_sensitive(slugs))
5857
}
5958

60-
pub fn encodable(self) -> EncodableCategory {
61-
let Category {
62-
crates_cnt,
63-
category,
64-
slug,
65-
description,
66-
created_at,
67-
..
68-
} = self;
69-
EncodableCategory {
70-
id: slug.clone(),
71-
slug,
72-
description,
73-
created_at,
74-
crates_cnt,
75-
category: category.rsplit("::").collect::<Vec<_>>()[0].to_string(),
76-
}
77-
}
78-
7959
pub fn update_crate(
8060
conn: &PgConnection,
8161
krate: &Crate,

src/models/krate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ impl Crate {
342342
};
343343
let keyword_ids = keywords.map(|kws| kws.iter().map(|kw| kw.keyword.clone()).collect());
344344
let category_ids = categories.map(|cats| cats.iter().map(|cat| cat.slug.clone()).collect());
345-
let badges = badges.map(|bs| bs.into_iter().map(Badge::encodable).collect());
345+
let badges = badges.map(|bs| bs.into_iter().map(Badge::into).collect());
346346
let documentation = Crate::remove_blocked_documentation_urls(documentation);
347347

348348
EncodableCrate {

src/views.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use chrono::NaiveDateTime;
22
use std::collections::HashMap;
33

4-
use crate::models::DependencyKind;
4+
use crate::models::{Badge, Category, DependencyKind};
55
use crate::util::rfc3339;
66

77
#[derive(PartialEq, Debug, Serialize, Deserialize)]
@@ -10,6 +10,13 @@ pub struct EncodableBadge {
1010
pub attributes: HashMap<String, Option<String>>,
1111
}
1212

13+
impl From<Badge> for EncodableBadge {
14+
fn from(badge: Badge) -> Self {
15+
// The serde attributes on Badge ensure it can be deserialized to EncodableBadge
16+
serde_json::from_value(serde_json::to_value(badge).unwrap()).unwrap()
17+
}
18+
}
19+
1320
#[derive(Serialize, Deserialize, Debug)]
1421
pub struct EncodableCategory {
1522
pub id: String,
@@ -21,6 +28,27 @@ pub struct EncodableCategory {
2128
pub crates_cnt: i32,
2229
}
2330

31+
impl From<Category> for EncodableCategory {
32+
fn from(category: Category) -> Self {
33+
let Category {
34+
crates_cnt,
35+
category,
36+
slug,
37+
description,
38+
created_at,
39+
..
40+
} = category;
41+
Self {
42+
id: slug.clone(),
43+
slug,
44+
description,
45+
created_at,
46+
crates_cnt,
47+
category: category.rsplit("::").collect::<Vec<_>>()[0].to_string(),
48+
}
49+
}
50+
}
51+
2452
#[derive(Serialize, Deserialize, Debug)]
2553
pub struct EncodableCategoryWithSubcategories {
2654
pub id: String,

0 commit comments

Comments
 (0)