Skip to content

Commit 8b1508f

Browse files
authored
Merge pull request #10703 from Turbo87/openapi-invites
Add OpenAPI documentation for `crate_owner_invitation` response payloads
2 parents b240999 + c7a329b commit 8b1508f

File tree

3 files changed

+224
-11
lines changed

3 files changed

+224
-11
lines changed

src/controllers/crate_owner_invitation.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,27 @@ use http::request::Parts;
2626
use indexmap::IndexMap;
2727
use std::collections::{HashMap, HashSet};
2828

29+
#[derive(Serialize, utoipa::ToSchema)]
30+
pub struct LegacyListResponse {
31+
/// The list of crate owner invitations.
32+
crate_owner_invitations: Vec<EncodableCrateOwnerInvitationV1>,
33+
34+
/// The list of users referenced in the crate owner invitations.
35+
users: Vec<EncodablePublicUser>,
36+
}
37+
2938
/// List all crate owner invitations for the authenticated user.
3039
#[utoipa::path(
3140
get,
3241
path = "/api/v1/me/crate_owner_invitations",
3342
security(("cookie" = [])),
3443
tag = "owners",
35-
responses((status = 200, description = "Successful Response")),
44+
responses((status = 200, description = "Successful Response", body = inline(LegacyListResponse))),
3645
)]
3746
pub async fn list_crate_owner_invitations_for_user(
3847
app: AppState,
3948
req: Parts,
40-
) -> AppResult<ErasedJson> {
49+
) -> AppResult<Json<LegacyListResponse>> {
4150
let mut conn = app.db_read().await?;
4251
let auth = AuthCheck::only_cookie().check(&req, &mut conn).await?;
4352

@@ -68,9 +77,9 @@ pub async fn list_crate_owner_invitations_for_user(
6877
})
6978
.collect::<AppResult<Vec<EncodableCrateOwnerInvitationV1>>>()?;
7079

71-
Ok(json!({
72-
"crate_owner_invitations": crate_owner_invitations,
73-
"users": users,
80+
Ok(Json(LegacyListResponse {
81+
crate_owner_invitations,
82+
users,
7483
}))
7584
}
7685

@@ -96,7 +105,7 @@ pub struct ListQueryParams {
96105
params(ListQueryParams, PaginationQueryParams),
97106
security(("cookie" = [])),
98107
tag = "owners",
99-
responses((status = 200, description = "Successful Response")),
108+
responses((status = 200, description = "Successful Response", body = inline(PrivateListResponse))),
100109
)]
101110
pub async fn list_crate_owner_invitations(
102111
app: AppState,
@@ -296,15 +305,22 @@ async fn prepare_list(
296305
})
297306
}
298307

299-
#[derive(Serialize)]
308+
#[derive(Serialize, utoipa::ToSchema)]
300309
pub struct PrivateListResponse {
310+
/// The list of crate owner invitations.
301311
invitations: Vec<EncodableCrateOwnerInvitation>,
312+
313+
/// The list of users referenced in the crate owner invitations.
302314
users: Vec<EncodablePublicUser>,
315+
316+
#[schema(inline)]
303317
meta: ResponseMeta,
304318
}
305319

306-
#[derive(Serialize)]
320+
#[derive(Serialize, utoipa::ToSchema)]
307321
struct ResponseMeta {
322+
/// Query parameter string to fetch the next page of results.
323+
#[schema(example = "?seek=c0ffee")]
308324
next_page: Option<String>,
309325
}
310326

src/snapshots/crates_io__openapi__tests__openapi_snapshot.snap

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,54 @@ expression: response.json()
7272
],
7373
"type": "object"
7474
},
75+
"CrateOwnerInvitation": {
76+
"properties": {
77+
"crate_id": {
78+
"description": "The ID of the crate that the user was invited to be an owner of.",
79+
"example": 123,
80+
"format": "int32",
81+
"type": "integer"
82+
},
83+
"crate_name": {
84+
"description": "The name of the crate that the user was invited to be an owner of.",
85+
"example": "serde",
86+
"type": "string"
87+
},
88+
"created_at": {
89+
"description": "The date and time this invitation was created.",
90+
"example": "2019-12-13T13:46:41Z",
91+
"format": "date-time",
92+
"type": "string"
93+
},
94+
"expires_at": {
95+
"description": "The date and time this invitation will expire.",
96+
"example": "2020-01-13T13:46:41Z",
97+
"format": "date-time",
98+
"type": "string"
99+
},
100+
"invitee_id": {
101+
"description": "The ID of the user who was invited to be a crate owner.",
102+
"example": 42,
103+
"format": "int32",
104+
"type": "integer"
105+
},
106+
"inviter_id": {
107+
"description": "The ID of the user who sent the invitation.",
108+
"example": 3,
109+
"format": "int32",
110+
"type": "integer"
111+
}
112+
},
113+
"required": [
114+
"invitee_id",
115+
"inviter_id",
116+
"crate_id",
117+
"crate_name",
118+
"created_at",
119+
"expires_at"
120+
],
121+
"type": "object"
122+
},
75123
"Keyword": {
76124
"properties": {
77125
"crates_cnt": {
@@ -105,6 +153,60 @@ expression: response.json()
105153
],
106154
"type": "object"
107155
},
156+
"LegacyCrateOwnerInvitation": {
157+
"properties": {
158+
"crate_id": {
159+
"description": "The ID of the crate that the user was invited to be an owner of.",
160+
"example": 123,
161+
"format": "int32",
162+
"type": "integer"
163+
},
164+
"crate_name": {
165+
"description": "The name of the crate that the user was invited to be an owner of.",
166+
"example": "serde",
167+
"type": "string"
168+
},
169+
"created_at": {
170+
"description": "The date and time this invitation was created.",
171+
"example": "2019-12-13T13:46:41Z",
172+
"format": "date-time",
173+
"type": "string"
174+
},
175+
"expires_at": {
176+
"description": "The date and time this invitation will expire.",
177+
"example": "2020-01-13T13:46:41Z",
178+
"format": "date-time",
179+
"type": "string"
180+
},
181+
"invited_by_username": {
182+
"description": "The username of the user who sent the invitation.",
183+
"example": "ghost",
184+
"type": "string"
185+
},
186+
"invitee_id": {
187+
"description": "The ID of the user who was invited to be a crate owner.",
188+
"example": 42,
189+
"format": "int32",
190+
"type": "integer"
191+
},
192+
"inviter_id": {
193+
"description": "The ID of the user who sent the invitation.",
194+
"example": 3,
195+
"format": "int32",
196+
"type": "integer"
197+
}
198+
},
199+
"required": [
200+
"invitee_id",
201+
"inviter_id",
202+
"invited_by_username",
203+
"crate_name",
204+
"crate_id",
205+
"created_at",
206+
"expires_at"
207+
],
208+
"type": "object"
209+
},
108210
"Slug": {
109211
"properties": {
110212
"description": {
@@ -261,6 +363,47 @@ expression: response.json()
261363
],
262364
"responses": {
263365
"200": {
366+
"content": {
367+
"application/json": {
368+
"schema": {
369+
"properties": {
370+
"invitations": {
371+
"description": "The list of crate owner invitations.",
372+
"items": {
373+
"$ref": "#/components/schemas/CrateOwnerInvitation"
374+
},
375+
"type": "array"
376+
},
377+
"meta": {
378+
"properties": {
379+
"next_page": {
380+
"description": "Query parameter string to fetch the next page of results.",
381+
"example": "?seek=c0ffee",
382+
"type": [
383+
"string",
384+
"null"
385+
]
386+
}
387+
},
388+
"type": "object"
389+
},
390+
"users": {
391+
"description": "The list of users referenced in the crate owner invitations.",
392+
"items": {
393+
"$ref": "#/components/schemas/User"
394+
},
395+
"type": "array"
396+
}
397+
},
398+
"required": [
399+
"invitations",
400+
"users",
401+
"meta"
402+
],
403+
"type": "object"
404+
}
405+
}
406+
},
264407
"description": "Successful Response"
265408
}
266409
},
@@ -1675,6 +1818,33 @@ expression: response.json()
16751818
"operationId": "list_crate_owner_invitations_for_user",
16761819
"responses": {
16771820
"200": {
1821+
"content": {
1822+
"application/json": {
1823+
"schema": {
1824+
"properties": {
1825+
"crate_owner_invitations": {
1826+
"description": "The list of crate owner invitations.",
1827+
"items": {
1828+
"$ref": "#/components/schemas/LegacyCrateOwnerInvitation"
1829+
},
1830+
"type": "array"
1831+
},
1832+
"users": {
1833+
"description": "The list of users referenced in the crate owner invitations.",
1834+
"items": {
1835+
"$ref": "#/components/schemas/User"
1836+
},
1837+
"type": "array"
1838+
}
1839+
},
1840+
"required": [
1841+
"crate_owner_invitations",
1842+
"users"
1843+
],
1844+
"type": "object"
1845+
}
1846+
}
1847+
},
16781848
"description": "Successful Response"
16791849
}
16801850
},

src/views.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,25 +79,52 @@ impl From<Category> for EncodableCategory {
7979
}
8080
}
8181

82-
/// The serialization format for the `CrateOwnerInvitation` model.
83-
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq)]
82+
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, utoipa::ToSchema)]
83+
#[schema(as = LegacyCrateOwnerInvitation)]
8484
pub struct EncodableCrateOwnerInvitationV1 {
85+
/// The ID of the user who was invited to be a crate owner.
86+
#[schema(example = 42)]
8587
pub invitee_id: i32,
88+
/// The ID of the user who sent the invitation.
89+
#[schema(example = 3)]
8690
pub inviter_id: i32,
91+
/// The username of the user who sent the invitation.
92+
#[schema(example = "ghost")]
8793
pub invited_by_username: String,
94+
/// The name of the crate that the user was invited to be an owner of.
95+
#[schema(example = "serde")]
8896
pub crate_name: String,
97+
/// The ID of the crate that the user was invited to be an owner of.
98+
#[schema(example = 123)]
8999
pub crate_id: i32,
100+
/// The date and time this invitation was created.
101+
#[schema(example = "2019-12-13T13:46:41Z")]
90102
pub created_at: DateTime<Utc>,
103+
/// The date and time this invitation will expire.
104+
#[schema(example = "2020-01-13T13:46:41Z")]
91105
pub expires_at: DateTime<Utc>,
92106
}
93107

94-
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq)]
108+
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, utoipa::ToSchema)]
109+
#[schema(as = CrateOwnerInvitation)]
95110
pub struct EncodableCrateOwnerInvitation {
111+
/// The ID of the user who was invited to be a crate owner.
112+
#[schema(example = 42)]
96113
pub invitee_id: i32,
114+
/// The ID of the user who sent the invitation.
115+
#[schema(example = 3)]
97116
pub inviter_id: i32,
117+
/// The ID of the crate that the user was invited to be an owner of.
118+
#[schema(example = 123)]
98119
pub crate_id: i32,
120+
/// The name of the crate that the user was invited to be an owner of.
121+
#[schema(example = "serde")]
99122
pub crate_name: String,
123+
/// The date and time this invitation was created.
124+
#[schema(example = "2019-12-13T13:46:41Z")]
100125
pub created_at: DateTime<Utc>,
126+
/// The date and time this invitation will expire.
127+
#[schema(example = "2020-01-13T13:46:41Z")]
101128
pub expires_at: DateTime<Utc>,
102129
}
103130

0 commit comments

Comments
 (0)