Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/controllers/user/other.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use axum::Json;
use axum::extract::Path;
use axum_extra::json;
use axum_extra::response::ErasedJson;
use bigdecimal::{BigDecimal, ToPrimitive};
use diesel::prelude::*;
use diesel_async::RunQueryDsl;
Expand Down Expand Up @@ -46,6 +44,13 @@ pub async fn find_user(
Ok(Json(GetResponse { user: user.into() }))
}

#[derive(Debug, Serialize, utoipa::ToSchema)]
pub struct StatsResponse {
/// The total number of downloads for crates owned by the user.
#[schema(example = 123_456_789)]
pub total_downloads: u64,
}

/// Get user stats.
///
/// This currently only returns the total number of downloads for crates owned
Expand All @@ -57,15 +62,18 @@ pub async fn find_user(
("id" = i32, Path, description = "ID of the user"),
),
tag = "users",
responses((status = 200, description = "Successful Response")),
responses((status = 200, description = "Successful Response", body = inline(StatsResponse))),
)]
pub async fn get_user_stats(state: AppState, Path(user_id): Path<i32>) -> AppResult<ErasedJson> {
pub async fn get_user_stats(
state: AppState,
Path(user_id): Path<i32>,
) -> AppResult<Json<StatsResponse>> {
let mut conn = state.db_read_prefer_primary().await?;

use diesel::dsl::sum;
use diesel_async::RunQueryDsl;

let data = CrateOwner::by_owner_kind(OwnerKind::User)
let total_downloads = CrateOwner::by_owner_kind(OwnerKind::User)
.inner_join(crates::table)
.inner_join(crate_downloads::table.on(crates::id.eq(crate_downloads::crate_id)))
.filter(crate_owners::owner_id.eq(user_id))
Expand All @@ -75,5 +83,5 @@ pub async fn get_user_stats(state: AppState, Path(user_id): Path<i32>) -> AppRes
.map(|d| d.to_u64().unwrap_or(u64::MAX))
.unwrap_or(0);

Ok(json!({ "total_downloads": data }))
Ok(Json(StatsResponse { total_downloads }))
}
19 changes: 19 additions & 0 deletions src/snapshots/crates_io__openapi__tests__openapi_snapshot.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2021,6 +2021,25 @@ expression: response.json()
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"total_downloads": {
"description": "The total number of downloads for crates owned by the user.",
"example": 123456789,
"format": "int64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"total_downloads"
],
"type": "object"
}
}
},
"description": "Successful Response"
}
},
Expand Down