diff --git a/app/components/crate-header.hbs b/app/components/crate-header.hbs
index 81d8e23d504..4e0ab00d868 100644
--- a/app/components/crate-header.hbs
+++ b/app/components/crate-header.hbs
@@ -54,7 +54,7 @@
- {{pluralize @crate.versions.length "Version"}}
+ {{pluralize @crate.num_versions "Version"}}
- All {{ this.model.versions.length }}
+ All {{ this.model.num_versions }}
versions of {{ this.model.name }} since
{{date-format this.model.created_at 'PPP'}}
diff --git a/packages/crates-io-msw/handlers/crates/get.test.js b/packages/crates-io-msw/handlers/crates/get.test.js
index 9fed9f1a89b..c3b2a51ef09 100644
--- a/packages/crates-io-msw/handlers/crates/get.test.js
+++ b/packages/crates-io-msw/handlers/crates/get.test.js
@@ -38,6 +38,7 @@ test('returns a crate object for known crates', async function () {
max_stable_version: null,
name: 'rand',
newest_version: '1.0.0-beta.1',
+ num_versions: 1,
repository: null,
recent_downloads: 321,
updated_at: '2017-02-24T12:34:56Z',
@@ -101,6 +102,7 @@ test('works for non-canonical names', async function () {
max_stable_version: null,
name: 'foo-bar',
newest_version: '1.0.0-beta.1',
+ num_versions: 1,
repository: null,
recent_downloads: 321,
updated_at: '2017-02-24T12:34:56Z',
diff --git a/packages/crates-io-msw/handlers/crates/list.test.js b/packages/crates-io-msw/handlers/crates/list.test.js
index c63ba8119f8..dcafbf659a4 100644
--- a/packages/crates-io-msw/handlers/crates/list.test.js
+++ b/packages/crates-io-msw/handlers/crates/list.test.js
@@ -55,6 +55,7 @@ test('returns a paginated crates list', async function () {
max_stable_version: '1.0.0',
name: 'rand',
newest_version: '2.0.0-beta.1',
+ num_versions: 2,
repository: null,
recent_downloads: 321,
updated_at: '2017-02-24T12:34:56Z',
diff --git a/packages/crates-io-msw/handlers/summary.test.js b/packages/crates-io-msw/handlers/summary.test.js
index 806a74e6994..a918470d167 100644
--- a/packages/crates-io-msw/handlers/summary.test.js
+++ b/packages/crates-io-msw/handlers/summary.test.js
@@ -51,6 +51,7 @@ test('returns the data for the front page', async function () {
max_stable_version: '1.0.0',
name: 'crate-1',
newest_version: '1.0.0',
+ num_versions: 1,
recent_downloads: 321,
repository: null,
updated_at: '2017-02-24T12:34:56Z',
@@ -81,6 +82,7 @@ test('returns the data for the front page', async function () {
max_stable_version: '1.0.3',
name: 'crate-4',
newest_version: '1.0.3',
+ num_versions: 1,
repository: null,
recent_downloads: 963,
updated_at: '2017-02-24T12:34:56Z',
@@ -111,6 +113,7 @@ test('returns the data for the front page', async function () {
max_stable_version: '1.0.10',
name: 'crate-11',
newest_version: '1.0.10',
+ num_versions: 1,
repository: null,
recent_downloads: 3852,
updated_at: '2017-02-24T12:34:56Z',
@@ -141,6 +144,7 @@ test('returns the data for the front page', async function () {
max_stable_version: '1.0.19',
name: 'crate-20',
newest_version: '1.0.19',
+ num_versions: 1,
repository: null,
recent_downloads: 1605,
updated_at: '2017-02-24T12:34:56Z',
diff --git a/packages/crates-io-msw/serializers/crate.js b/packages/crates-io-msw/serializers/crate.js
index d6004e5a5df..5b21db89192 100644
--- a/packages/crates-io-msw/serializers/crate.js
+++ b/packages/crates-io-msw/serializers/crate.js
@@ -27,6 +27,8 @@ export function serializeCrate(
versionNums.find(it => !versionsByNum[it].yanked) ??
versionNums[0];
+ serialized.num_versions = versions.length;
+
serialized.yanked = versionsByNum[serialized.default_version]?.yanked ?? false;
serialized.links = {
diff --git a/src/controllers/krate/metadata.rs b/src/controllers/krate/metadata.rs
index d259a5fea94..9f77a9347ae 100644
--- a/src/controllers/krate/metadata.rs
+++ b/src/controllers/krate/metadata.rs
@@ -75,21 +75,27 @@ pub async fn find_crate(
.transpose()?
.unwrap_or_default();
- let (krate, downloads, default_version, yanked): (Crate, i64, Option, Option) =
- Crate::by_name(&path.name)
- .inner_join(crate_downloads::table)
- .left_join(default_versions::table)
- .left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
- .select((
- Crate::as_select(),
- crate_downloads::downloads,
- versions::num.nullable(),
- versions::yanked.nullable(),
- ))
- .first(&mut conn)
- .await
- .optional()?
- .ok_or_else(|| crate_not_found(&path.name))?;
+ let (krate, downloads, default_version, yanked, num_versions): (
+ Crate,
+ i64,
+ Option,
+ Option,
+ Option,
+ ) = Crate::by_name(&path.name)
+ .inner_join(crate_downloads::table)
+ .left_join(default_versions::table)
+ .left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
+ .select((
+ Crate::as_select(),
+ crate_downloads::downloads,
+ versions::num.nullable(),
+ versions::yanked.nullable(),
+ default_versions::num_versions.nullable(),
+ ))
+ .first(&mut conn)
+ .await
+ .optional()?
+ .ok_or_else(|| crate_not_found(&path.name))?;
let mut versions_publishers_and_audit_actions = if include.versions {
let versions_and_publishers: Vec<(Version, Option)> = Version::belonging_to(&krate)
@@ -183,6 +189,7 @@ pub async fn find_crate(
let encodable_crate = EncodableCrate::from(
krate.clone(),
default_version.as_deref(),
+ num_versions.unwrap_or_default(),
yanked,
top_versions.as_ref(),
ids,
diff --git a/src/controllers/krate/publish.rs b/src/controllers/krate/publish.rs
index 0decc4d9b6b..26f4f7a9df2 100644
--- a/src/controllers/krate/publish.rs
+++ b/src/controllers/krate/publish.rs
@@ -436,11 +436,12 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult)>(conn)
.await
.optional()?;
+ let num_versions = existing_default_version.as_ref().and_then(|t|t.1).unwrap_or_default();
let mut default_version = None;
// Upsert the `default_value` determined by the existing `default_value` and the
// published version. Note that this could potentially write an outdated version
@@ -450,7 +451,7 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult AppResult(),
versions::num.nullable(),
versions::yanked.nullable(),
+ default_versions::num_versions.nullable(),
);
let mut seek: Option = None;
@@ -113,6 +114,7 @@ pub async fn list_crates(
rank,
versions::num.nullable(),
versions::yanked.nullable(),
+ default_versions::num_versions.nullable(),
));
seek = Some(Seek::Relevance);
query = query.then_order_by(rank.desc())
@@ -125,6 +127,7 @@ pub async fn list_crates(
0_f32.into_sql::(),
versions::num.nullable(),
versions::yanked.nullable(),
+ default_versions::num_versions.nullable(),
));
seek = Some(Seek::Query);
}
@@ -227,6 +230,7 @@ pub async fn list_crates(
EncodableCrate::from_minimal(
record.krate,
record.default_version.as_deref(),
+ record.num_versions.unwrap_or_default(),
record.yanked,
Some(&max_version),
record.exact_match,
@@ -704,6 +708,7 @@ struct Record {
rank: f32,
default_version: Option,
yanked: Option,
+ num_versions: Option,
}
type QuerySource = LeftJoinQuerySource<
diff --git a/src/controllers/summary.rs b/src/controllers/summary.rs
index 30fa196c3c1..7dd2694a92d 100644
--- a/src/controllers/summary.rs
+++ b/src/controllers/summary.rs
@@ -135,6 +135,8 @@ struct Record {
default_version: Option,
#[diesel(select_expression = versions::columns::yanked.nullable())]
yanked: Option,
+ #[diesel(select_expression = default_versions::columns::num_versions.nullable())]
+ num_versions: Option,
}
fn encode_crates(
@@ -165,6 +167,7 @@ fn encode_crates(
Ok(EncodableCrate::from_minimal(
record.krate,
record.default_version.as_deref(),
+ record.num_versions.unwrap_or_default(),
record.yanked,
Some(&top_versions),
false,
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap
index 0365b6ccfa3..28cb4db0450 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo_new",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap
index d959bcaa0fb..501d39ee175 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "2.0.0",
"name": "foo_twice",
"newest_version": "2.0.0",
+ "num_versions": 2,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap
index faf28612baf..06a5033f589 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "2.0.0",
"name": "foo_twice",
"newest_version": "0.99.0",
+ "num_versions": 2,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap
index ef9e159a689..72ade9bb92e 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "0.0.0-pre",
"name": "foo_weird",
"newest_version": "0.0.0-pre",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap
index 0365b6ccfa3..28cb4db0450 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo_new",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap
index d13d9369710..41b3c2f3247 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0+foo",
"name": "foo",
"newest_version": "1.0.0+foo",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap
index b1c0ebc2b4c..c4b64395e8e 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0-beta.1",
"name": "foo",
"newest_version": "1.0.0-beta.1",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap
index d13d9369710..41b3c2f3247 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0+foo",
"name": "foo",
"newest_version": "1.0.0+foo",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap
index 165c2ab3786..26be0235fbd 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo_good_cat",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap
index 6c3a975825c..469fe526ce4 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap
index 94b597a6f4b..7a884ebe94e 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap
index d05f0cba378..88d74b8c9d9 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo_good_key",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap
index 0456f01fb9e..07e0cfe632c 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap
index 7782eadcd2e..c0787b7c239 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap
index 7782eadcd2e..c0787b7c239 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap
index bdf0b47ea19..c2acc59eeb3 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.1.0",
"name": "foo",
"newest_version": "1.1.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap
index 961fbe387de..1b92337edd3 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo_readme",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap
index 961fbe387de..1b92337edd3 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo_readme",
"newest_version": "1.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap
index b18206501b0..85f7ef58068 100644
--- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap
+++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap
@@ -27,6 +27,7 @@ expression: response.json()
"max_version": "1.0.0+foo",
"name": "foo_readme",
"newest_version": "1.0.0+foo",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap
index 11f3d480479..c7b079c37a4 100644
--- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap
+++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap
@@ -28,6 +28,7 @@ expression: response.json()
"max_version": "0.0.0",
"name": "foo_default_version",
"newest_version": "0.0.0",
+ "num_versions": 3,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap
index 026be79f9c0..991a1909f2c 100644
--- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap
+++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap
@@ -28,6 +28,7 @@ expression: response.json()
"max_version": "0.0.0",
"name": "new",
"newest_version": "0.0.0",
+ "num_versions": 1,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap
index dd145a4139f..75c2cd698be 100644
--- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap
+++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap
@@ -30,6 +30,7 @@ expression: response.json()
"max_version": "1.0.0",
"name": "foo_show",
"newest_version": "0.5.1",
+ "num_versions": 3,
"recent_downloads": 10,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap
index fcd31e61706..30269ad6920 100644
--- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap
+++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap
@@ -30,6 +30,7 @@ expression: response.json()
"max_version": "0.0.0",
"name": "foo_show",
"newest_version": "0.0.0",
+ "num_versions": 2,
"recent_downloads": 10,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap
index a040d208028..d1480ec96ef 100644
--- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap
+++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap
@@ -28,6 +28,7 @@ expression: response.json()
"max_version": "0.0.0",
"name": "foo_show_minimal",
"newest_version": "0.0.0",
+ "num_versions": 3,
"recent_downloads": null,
"repository": null,
"updated_at": "[datetime]",
diff --git a/src/views.rs b/src/views.rs
index 72492d664d3..b7503739db0 100644
--- a/src/views.rs
+++ b/src/views.rs
@@ -207,6 +207,7 @@ pub struct EncodableCrate {
pub downloads: i64,
pub recent_downloads: Option,
pub default_version: Option,
+ pub num_versions: i32,
pub yanked: bool,
// NOTE: Used by shields.io, altering `max_version` requires a PR with shields.io
pub max_version: String,
@@ -225,6 +226,7 @@ impl EncodableCrate {
pub fn from(
krate: Crate,
default_version: Option<&str>,
+ num_versions: i32,
yanked: Option,
top_versions: Option<&TopVersions>,
versions: Option>,
@@ -297,6 +299,7 @@ impl EncodableCrate {
categories: category_ids,
badges: [],
default_version,
+ num_versions,
yanked,
max_version,
newest_version,
@@ -317,9 +320,11 @@ impl EncodableCrate {
}
}
+ #[allow(clippy::too_many_arguments)]
pub fn from_minimal(
krate: Crate,
default_version: Option<&str>,
+ num_versions: i32,
yanked: Option,
top_versions: Option<&TopVersions>,
exact_match: bool,
@@ -329,6 +334,7 @@ impl EncodableCrate {
Self::from(
krate,
default_version,
+ num_versions,
yanked,
top_versions,
None,
@@ -823,6 +829,7 @@ mod tests {
downloads: 0,
recent_downloads: None,
default_version: None,
+ num_versions: 0,
yanked: false,
max_version: "".to_string(),
newest_version: "".to_string(),