Skip to content

Commit caec94e

Browse files
committed
Refactor top_version into the version module
Where we used to have max_version, we now have two kinds of top versions: - the highest semver version - the most recently updated version.
1 parent 8143165 commit caec94e

File tree

4 files changed

+50
-87
lines changed

4 files changed

+50
-87
lines changed

src/controllers/krate/metadata.rs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
//! Endpoints that expose metadata about a crate
22
//!
3-
//! These endpoints provide data that could be obtained direclty from the
3+
//! These endpoints provide data that could be obtained directly from the
44
//! index or cached metadata which was extracted (client side) from the
55
//! `Cargo.toml` file.
66
7-
use chrono::NaiveDateTime;
8-
97
use crate::controllers::prelude::*;
10-
use crate::models::krate::TopVersions;
118
use crate::models::user;
129
use crate::models::user::UserNoEmailType;
1310
use crate::models::{
@@ -36,26 +33,7 @@ pub fn summary(req: &mut dyn Request) -> AppResult<Response> {
3633
versions
3734
.grouped_by(&krates)
3835
.into_iter()
39-
.map(|versions| {
40-
let pairs: Vec<_> = versions
41-
.into_iter()
42-
.map(|version| (version.created_at, version.num.to_string()))
43-
.collect();
44-
TopVersions {
45-
newest: pairs
46-
.to_owned()
47-
.into_iter()
48-
.max()
49-
.unwrap_or((NaiveDateTime::from_timestamp(0, 0), "0.0.0".to_owned()))
50-
.1,
51-
highest: Version::max(
52-
pairs
53-
.into_iter()
54-
.map(|(_, s)| semver::Version::parse(&s).unwrap()),
55-
)
56-
.to_string(),
57-
}
58-
})
36+
.map(|versions| Version::top(versions.into_iter().map(|v| (v.created_at, v.num))))
5937
.zip(krates)
6038
.map(|(top_versions, krate)| {
6139
Ok(krate.minimal_encodable(&top_versions, None, false, None))

src/controllers/krate/search.rs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
//! Endpoint for searching and discovery functionality
22
3-
use chrono::NaiveDateTime;
43
use diesel::dsl::*;
54
use diesel_full_text_search::*;
65

76
use crate::controllers::helpers::Paginate;
87
use crate::controllers::prelude::*;
9-
use crate::models::krate::TopVersions;
108
use crate::models::{Crate, CrateBadge, CrateOwner, CrateVersions, OwnerKind, Version};
119
use crate::schema::*;
1210
use crate::views::EncodableCrate;
@@ -181,26 +179,7 @@ pub fn search(req: &mut dyn Request) -> AppResult<Response> {
181179
.load::<Version>(&*conn)?
182180
.grouped_by(&crates)
183181
.into_iter()
184-
.map(|versions| {
185-
let pairs: Vec<_> = versions
186-
.into_iter()
187-
.map(|version| (version.created_at, version.num.to_string()))
188-
.collect();
189-
TopVersions {
190-
newest: pairs
191-
.to_owned()
192-
.into_iter()
193-
.max()
194-
.unwrap_or((NaiveDateTime::from_timestamp(0, 0), "0.0.0".to_owned()))
195-
.1,
196-
highest: Version::max(
197-
pairs
198-
.into_iter()
199-
.map(|(_, s)| semver::Version::parse(&s).unwrap()),
200-
)
201-
.to_string(),
202-
}
203-
});
182+
.map(|versions| Version::top(versions.into_iter().map(|v| (v.created_at, v.num))));
204183

205184
let badges = CrateBadge::belonging_to(&crates)
206185
.select((badges::crate_id, badges::all_columns))

src/models/krate.rs

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::app::App;
1010
use crate::email;
1111
use crate::models::user;
1212
use crate::models::user::UserNoEmailType;
13+
use crate::models::version::TopVersions;
1314
use crate::util::{cargo_err, AppResult};
1415

1516
use crate::models::{
@@ -50,14 +51,6 @@ pub struct Crate {
5051
pub max_upload_size: Option<i32>,
5152
}
5253

53-
/// The highest version (in semver order) and the most recently updated version
54-
/// for a single crate.
55-
#[derive(Debug, Clone)]
56-
pub struct TopVersions {
57-
pub highest: String,
58-
pub newest: String,
59-
}
60-
6154
/// We literally never want to select `textsearchable_index_col`
6255
/// so we provide this type and constant to pass to `.select`
6356
type AllColumns = (
@@ -349,8 +342,8 @@ impl Crate {
349342
keywords: keyword_ids,
350343
categories: category_ids,
351344
badges,
352-
max_version: top_versions.highest.to_owned(),
353-
newest_version: top_versions.newest.to_owned(),
345+
max_version: top_versions.highest.to_string(),
346+
newest_version: top_versions.newest.to_string(),
354347
documentation,
355348
homepage,
356349
exact_match,
@@ -400,25 +393,11 @@ impl Crate {
400393
pub fn top_versions(&self, conn: &PgConnection) -> AppResult<TopVersions> {
401394
use crate::schema::versions::dsl::*;
402395

403-
let results = self
404-
.versions()
405-
.select((updated_at, num))
406-
.load::<(NaiveDateTime, String)>(conn)?;
407-
408-
Ok(TopVersions {
409-
newest: results
410-
.to_owned()
411-
.into_iter()
412-
.max()
413-
.unwrap_or((NaiveDateTime::from_timestamp(0, 0), "0.0.0".to_owned()))
414-
.1,
415-
highest: Version::max(
416-
results
417-
.into_iter()
418-
.map(|(_, s)| semver::Version::parse(&s).unwrap()),
419-
)
420-
.to_string(),
421-
})
396+
Ok(Version::top(
397+
self.versions()
398+
.select((updated_at, num))
399+
.load::<(NaiveDateTime, semver::Version)>(conn)?,
400+
))
422401
}
423402

424403
pub fn owners(&self, conn: &PgConnection) -> AppResult<Vec<Owner>> {

src/models/version.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,25 @@ pub struct NewVersion {
3939
published_by: i32,
4040
}
4141

42+
/// The highest version (semver order) and the most recently updated version.
43+
/// Typically used for a single crate.
44+
#[derive(Debug, Clone)]
45+
pub struct TopVersions {
46+
pub highest: semver::Version,
47+
pub newest: semver::Version,
48+
}
49+
50+
/// A default semver value, "0.0.0", for use in TopVersions
51+
fn default_semver_version() -> semver::Version {
52+
semver::Version {
53+
major: 0,
54+
minor: 0,
55+
patch: 0,
56+
pre: vec![],
57+
build: vec![],
58+
}
59+
}
60+
4261
impl Version {
4362
pub fn encodable(self, crate_name: &str, published_by: Option<User>) -> EncodableVersion {
4463
let Version {
@@ -85,20 +104,28 @@ impl Version {
85104
.load(conn)
86105
}
87106

88-
pub fn max<T>(versions: T) -> semver::Version
107+
/// Return both the newest (most recently updated) and the
108+
/// highest version (in semver order) for a collection of date/version pairs.
109+
pub fn top<T>(pairs: T) -> TopVersions
89110
where
90-
T: IntoIterator<Item = semver::Version>,
111+
T: Clone + IntoIterator<Item = (NaiveDateTime, semver::Version)>,
91112
{
92-
versions
93-
.into_iter()
94-
.max()
95-
.unwrap_or_else(|| semver::Version {
96-
major: 0,
97-
minor: 0,
98-
patch: 0,
99-
pre: vec![],
100-
build: vec![],
101-
})
113+
TopVersions {
114+
newest: pairs
115+
.clone()
116+
.into_iter()
117+
.max()
118+
.unwrap_or((
119+
NaiveDateTime::from_timestamp(0, 0),
120+
default_semver_version(),
121+
))
122+
.1,
123+
highest: pairs
124+
.into_iter()
125+
.map(|(_, v)| v)
126+
.max()
127+
.unwrap_or_else(default_semver_version),
128+
}
102129
}
103130

104131
pub fn record_readme_rendering(version_id_: i32, conn: &PgConnection) -> QueryResult<usize> {

0 commit comments

Comments
 (0)