utoipa_helper/
json_response.rs1use axum::Json;
2use axum::http::header::HeaderValue;
3use axum::http::header::SET_COOKIE;
4use axum::response::IntoResponse;
5use serde::Serialize;
6use std::convert::TryFrom;
7use utoipa::PartialSchema;
8use utoipa::ToSchema;
9
10pub struct JsonResponse<T>
11where
12 T: ToSchema + Serialize + Send,
13{
14 data: T,
15 cookies: Option<Vec<String>>,
16}
17
18impl<T> JsonResponse<T>
19where
20 T: ToSchema + Serialize + Send,
21{
22 pub fn new(data: T) -> Self {
23 Self {
24 data,
25 cookies: None,
26 }
27 }
28
29 #[must_use]
30 pub fn with_cookie(mut self, cookie: impl Into<String>) -> Self {
31 if let Some(cookies) = self.cookies.as_mut() {
32 cookies.push(cookie.into());
33 } else {
34 self.cookies = Some(vec![cookie.into()]);
35 }
36 self
37 }
38}
39
40impl<T> IntoResponse for JsonResponse<T>
41where
42 T: ToSchema + Serialize + Send,
43{
44 fn into_response(self) -> axum::response::Response {
45 let mut res = Json(self.data).into_response();
46 if let Some(cookies) = self.cookies {
47 for cookie in cookies {
48 if let Ok(value) = <HeaderValue as TryFrom<String>>::try_from(cookie) {
49 res.headers_mut().append(SET_COOKIE, value);
50 }
51 }
52 }
53 res
54 }
55}
56
57impl<T> PartialSchema for JsonResponse<T>
58where
59 T: ToSchema + Serialize + Send,
60{
61 fn schema() -> utoipa::openapi::RefOr<utoipa::openapi::schema::Schema> {
62 T::schema()
63 }
64}
65
66impl<T> ToSchema for JsonResponse<T>
67where
68 T: ToSchema + Serialize + Send,
69{
70 fn name() -> std::borrow::Cow<'static, str> {
71 T::name()
72 }
73
74 fn schemas(
75 schemas: &mut Vec<(
76 String,
77 utoipa::openapi::RefOr<utoipa::openapi::schema::Schema>,
78 )>,
79 ) {
80 T::schemas(schemas);
81 }
82}