Skip to content

Commit 4443a10

Browse files
committed
controllers/category: Extract ListQueryParams struct
1 parent 541e1a9 commit 4443a10

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

src/controllers/category.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,47 @@ use crate::app::AppState;
33
use crate::models::Category;
44
use crate::schema::categories;
55
use crate::util::errors::AppResult;
6-
use crate::util::RequestUtils;
76
use crate::views::{EncodableCategory, EncodableCategoryWithSubcategories};
8-
use axum::extract::Path;
7+
use axum::extract::{FromRequestParts, Path, Query};
98
use axum_extra::json;
109
use axum_extra::response::ErasedJson;
1110
use diesel::QueryDsl;
1211
use diesel_async::RunQueryDsl;
1312
use http::request::Parts;
1413

14+
#[derive(Debug, Deserialize, FromRequestParts, utoipa::IntoParams)]
15+
#[from_request(via(Query))]
16+
#[into_params(parameter_in = Query)]
17+
pub struct ListQueryParams {
18+
/// The sort order of the categories.
19+
///
20+
/// Valid values: `alpha`, and `crates`.
21+
///
22+
/// Defaults to `alpha`.
23+
sort: Option<String>,
24+
}
25+
1526
/// List all categories.
1627
#[utoipa::path(
1728
get,
1829
path = "/api/v1/categories",
30+
params(ListQueryParams, PaginationQueryParams),
1931
tag = "categories",
2032
responses((status = 200, description = "Successful Response")),
2133
)]
22-
pub async fn list_categories(app: AppState, req: Parts) -> AppResult<ErasedJson> {
34+
pub async fn list_categories(
35+
app: AppState,
36+
params: ListQueryParams,
37+
req: Parts,
38+
) -> AppResult<ErasedJson> {
2339
// FIXME: There are 69 categories, 47 top level. This isn't going to
2440
// grow by an OoM. We need a limit for /summary, but we don't need
2541
// to paginate this.
2642
let options = PaginationOptions::builder().gather(&req)?;
2743

2844
let mut conn = app.db_read().await?;
2945

30-
let query = req.query();
31-
let sort = query.get("sort").map_or("alpha", String::as_str);
46+
let sort = params.sort.as_ref().map_or("alpha", String::as_str);
3247

3348
let offset = options.offset().unwrap_or_default();
3449

src/snapshots/crates_io__openapi__tests__openapi_snapshot.snap

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,60 @@ snapshot_kind: text
8181
"/api/v1/categories": {
8282
"get": {
8383
"operationId": "list_categories",
84+
"parameters": [
85+
{
86+
"description": "The sort order of the categories.\n\nValid values: `alpha`, and `crates`.\n\nDefaults to `alpha`.",
87+
"in": "query",
88+
"name": "sort",
89+
"required": false,
90+
"schema": {
91+
"type": [
92+
"string",
93+
"null"
94+
]
95+
}
96+
},
97+
{
98+
"description": "The page number to request.\n\nThis parameter is mutually exclusive with `seek` and not supported for\nall requests.",
99+
"in": "query",
100+
"name": "page",
101+
"required": false,
102+
"schema": {
103+
"format": "int32",
104+
"minimum": 1,
105+
"type": [
106+
"integer",
107+
"null"
108+
]
109+
}
110+
},
111+
{
112+
"description": "The number of items to request per page.",
113+
"in": "query",
114+
"name": "per_page",
115+
"required": false,
116+
"schema": {
117+
"format": "int32",
118+
"minimum": 1,
119+
"type": [
120+
"integer",
121+
"null"
122+
]
123+
}
124+
},
125+
{
126+
"description": "The seek key to request.\n\nThis parameter is mutually exclusive with `page` and not supported for\nall requests.\n\nThe seek key can usually be found in the `meta.next_page` field of\npaginated responses.",
127+
"in": "query",
128+
"name": "seek",
129+
"required": false,
130+
"schema": {
131+
"type": [
132+
"string",
133+
"null"
134+
]
135+
}
136+
}
137+
],
84138
"responses": {
85139
"200": {
86140
"description": "Successful Response"

0 commit comments

Comments
 (0)