1use std::{
2 marker::PhantomData,
3 ops::{Deref, DerefMut},
4};
5
6use serde::{Deserialize, Serialize};
7
8use crate::generate::GenContext;
9use crate::openapi::{Operation, Response};
10use crate::{OperationInput, OperationOutput};
11
12pub trait IntoApi {
14 fn into_api<A>(self) -> UseApi<Self, A>
16 where
17 Self: Sized;
18}
19
20impl<T> IntoApi for T {
21 fn into_api<A>(self) -> UseApi<Self, A>
22 where
23 Self: Sized,
24 {
25 self.into()
26 }
27}
28
29#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
33pub struct UseApi<T, A>(pub T, pub PhantomData<A>);
34
35impl<T, A> UseApi<T, A> {
36 pub fn into_inner(self) -> T {
38 self.0
39 }
40}
41
42impl<T, A> Deref for UseApi<T, A> {
43 type Target = T;
44
45 fn deref(&self) -> &Self::Target {
46 &self.0
47 }
48}
49
50impl<T, A> DerefMut for UseApi<T, A> {
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 &mut self.0
53 }
54}
55
56impl<T, A> AsRef<T> for UseApi<T, A> {
57 fn as_ref(&self) -> &T {
58 &self.0
59 }
60}
61
62impl<T, A> AsMut<T> for UseApi<T, A> {
63 fn as_mut(&mut self) -> &mut T {
64 &mut self.0
65 }
66}
67
68impl<T, A> From<T> for UseApi<T, A> {
69 fn from(value: T) -> Self {
70 Self(value, Default::default())
71 }
72}
73
74impl<T, A> OperationInput for UseApi<T, A>
75where
76 A: OperationInput,
77{
78 fn operation_input(ctx: &mut GenContext, operation: &mut Operation) {
79 A::operation_input(ctx, operation);
80 }
81
82 fn inferred_early_responses(
83 ctx: &mut GenContext,
84 operation: &mut Operation,
85 ) -> Vec<(Option<u16>, Response)> {
86 A::inferred_early_responses(ctx, operation)
87 }
88}
89
90impl<T, A> OperationOutput for UseApi<T, A>
91where
92 A: OperationOutput,
93{
94 type Inner = A::Inner;
95
96 fn operation_response(ctx: &mut GenContext, operation: &mut Operation) -> Option<Response> {
97 A::operation_response(ctx, operation)
98 }
99
100 fn inferred_responses(
101 ctx: &mut GenContext,
102 operation: &mut Operation,
103 ) -> Vec<(Option<u16>, Response)> {
104 A::inferred_responses(ctx, operation)
105 }
106}
107
108#[cfg(feature = "axum")]
109mod axum {
110 use axum::body::Body;
111 use axum::extract::{FromRequest, FromRequestParts};
112 use axum::response::{IntoResponse, IntoResponseParts, Response, ResponseParts};
113 use http::request::Parts;
114 use http::Request;
115
116 use crate::UseApi;
117
118 impl<T, A> IntoResponse for UseApi<T, A>
119 where
120 T: IntoResponse,
121 {
122 fn into_response(self) -> Response {
123 self.0.into_response()
124 }
125 }
126
127 impl<T, A> IntoResponseParts for UseApi<T, A>
128 where
129 T: IntoResponseParts,
130 {
131 type Error = T::Error;
132
133 fn into_response_parts(self, res: ResponseParts) -> Result<ResponseParts, Self::Error> {
134 self.0.into_response_parts(res)
135 }
136 }
137
138 impl<T, A, S> FromRequestParts<S> for UseApi<T, A>
139 where
140 T: FromRequestParts<S>,
141 S: Send + Sync,
142 {
143 type Rejection = T::Rejection;
144
145 async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
146 Ok(Self(
147 T::from_request_parts(parts, state).await?,
148 Default::default(),
149 ))
150 }
151 }
152
153 impl<T, A, S> FromRequest<S> for UseApi<T, A>
154 where
155 T: FromRequest<S>,
156 S: Send + Sync,
157 {
158 type Rejection = T::Rejection;
159
160 async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
161 Ok(Self(T::from_request(req, state).await?, Default::default()))
162 }
163 }
164}