1 /// Private API.
2 #[doc(hidden)]
3 #[macro_export]
4 macro_rules! __log_rejection {
5     (
6         rejection_type = $ty:ident,
7         body_text = $body_text:expr,
8         status = $status:expr,
9     ) => {
10         #[cfg(feature = "tracing")]
11         {
12             tracing::event!(
13                 target: "axum::rejection",
14                 tracing::Level::TRACE,
15                 status = $status.as_u16(),
16                 body = $body_text,
17                 rejection_type = std::any::type_name::<$ty>(),
18                 "rejecting request",
19             );
20         }
21     };
22 }
23 
24 /// Private API.
25 #[doc(hidden)]
26 #[macro_export]
27 macro_rules! __define_rejection {
28     (
29         #[status = $status:ident]
30         #[body = $body:expr]
31         $(#[$m:meta])*
32         pub struct $name:ident;
33     ) => {
34         $(#[$m])*
35         #[derive(Debug)]
36         #[non_exhaustive]
37         pub struct $name;
38 
39         impl $crate::response::IntoResponse for $name {
40             fn into_response(self) -> $crate::response::Response {
41                 $crate::__log_rejection!(
42                     rejection_type = $name,
43                     body_text = $body,
44                     status = http::StatusCode::$status,
45                 );
46                 (self.status(), $body).into_response()
47             }
48         }
49 
50         impl $name {
51             /// Get the response body text used for this rejection.
52             pub fn body_text(&self) -> String {
53                 $body.into()
54             }
55 
56             /// Get the status code used for this rejection.
57             pub fn status(&self) -> http::StatusCode {
58                 http::StatusCode::$status
59             }
60         }
61 
62         impl std::fmt::Display for $name {
63             fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64                 write!(f, "{}", $body)
65             }
66         }
67 
68         impl std::error::Error for $name {}
69 
70         impl Default for $name {
71             fn default() -> Self {
72                 Self
73             }
74         }
75     };
76 
77     (
78         #[status = $status:ident]
79         #[body = $body:expr]
80         $(#[$m:meta])*
81         pub struct $name:ident (Error);
82     ) => {
83         $(#[$m])*
84         #[derive(Debug)]
85         pub struct $name(pub(crate) $crate::Error);
86 
87         impl $name {
88             pub(crate) fn from_err<E>(err: E) -> Self
89             where
90                 E: Into<$crate::BoxError>,
91             {
92                 Self($crate::Error::new(err))
93             }
94         }
95 
96         impl $crate::response::IntoResponse for $name {
97             fn into_response(self) -> $crate::response::Response {
98                 $crate::__log_rejection!(
99                     rejection_type = $name,
100                     body_text = self.body_text(),
101                     status = http::StatusCode::$status,
102                 );
103                 (self.status(), self.body_text()).into_response()
104             }
105         }
106 
107         impl $name {
108             /// Get the response body text used for this rejection.
109             pub fn body_text(&self) -> String {
110                 format!(concat!($body, ": {}"), self.0).into()
111             }
112 
113             /// Get the status code used for this rejection.
114             pub fn status(&self) -> http::StatusCode {
115                 http::StatusCode::$status
116             }
117         }
118 
119         impl std::fmt::Display for $name {
120             fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121                 write!(f, "{}", $body)
122             }
123         }
124 
125         impl std::error::Error for $name {
126             fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
127                 Some(&self.0)
128             }
129         }
130     };
131 }
132 
133 /// Private API.
134 #[doc(hidden)]
135 #[macro_export]
136 macro_rules! __composite_rejection {
137     (
138         $(#[$m:meta])*
139         pub enum $name:ident {
140             $($variant:ident),+
141             $(,)?
142         }
143     ) => {
144         $(#[$m])*
145         #[derive(Debug)]
146         #[non_exhaustive]
147         pub enum $name {
148             $(
149                 #[allow(missing_docs)]
150                 $variant($variant)
151             ),+
152         }
153 
154         impl $crate::response::IntoResponse for $name {
155             fn into_response(self) -> $crate::response::Response {
156                 match self {
157                     $(
158                         Self::$variant(inner) => inner.into_response(),
159                     )+
160                 }
161             }
162         }
163 
164         impl $name {
165             /// Get the response body text used for this rejection.
166             pub fn body_text(&self) -> String {
167                 match self {
168                     $(
169                         Self::$variant(inner) => inner.body_text(),
170                     )+
171                 }
172             }
173 
174             /// Get the status code used for this rejection.
175             pub fn status(&self) -> http::StatusCode {
176                 match self {
177                     $(
178                         Self::$variant(inner) => inner.status(),
179                     )+
180                 }
181             }
182         }
183 
184         $(
185             impl From<$variant> for $name {
186                 fn from(inner: $variant) -> Self {
187                     Self::$variant(inner)
188                 }
189             }
190         )+
191 
192         impl std::fmt::Display for $name {
193             fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194                 match self {
195                     $(
196                         Self::$variant(inner) => write!(f, "{}", inner),
197                     )+
198                 }
199             }
200         }
201 
202         impl std::error::Error for $name {
203             fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
204                 match self {
205                     $(
206                         Self::$variant(inner) => Some(inner),
207                     )+
208                 }
209             }
210         }
211     };
212 }
213 
214 #[rustfmt::skip]
215 macro_rules! all_the_tuples {
216     ($name:ident) => {
217         $name!([], T1);
218         $name!([T1], T2);
219         $name!([T1, T2], T3);
220         $name!([T1, T2, T3], T4);
221         $name!([T1, T2, T3, T4], T5);
222         $name!([T1, T2, T3, T4, T5], T6);
223         $name!([T1, T2, T3, T4, T5, T6], T7);
224         $name!([T1, T2, T3, T4, T5, T6, T7], T8);
225         $name!([T1, T2, T3, T4, T5, T6, T7, T8], T9);
226         $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9], T10);
227         $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], T11);
228         $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], T12);
229         $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], T13);
230         $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], T14);
231         $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], T15);
232         $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], T16);
233     };
234 }
235 
236 macro_rules! all_the_tuples_no_last_special_case {
237     ($name:ident) => {
238         $name!(T1);
239         $name!(T1, T2);
240         $name!(T1, T2, T3);
241         $name!(T1, T2, T3, T4);
242         $name!(T1, T2, T3, T4, T5);
243         $name!(T1, T2, T3, T4, T5, T6);
244         $name!(T1, T2, T3, T4, T5, T6, T7);
245         $name!(T1, T2, T3, T4, T5, T6, T7, T8);
246         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
247         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
248         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
249         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
250         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
251         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
252         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);
253         $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);
254     };
255 }
256 
257 /// Private API.
258 #[doc(hidden)]
259 #[macro_export]
260 macro_rules! __impl_deref {
261     ($ident:ident) => {
262         impl<T> std::ops::Deref for $ident<T> {
263             type Target = T;
264 
265             #[inline]
266             fn deref(&self) -> &Self::Target {
267                 &self.0
268             }
269         }
270 
271         impl<T> std::ops::DerefMut for $ident<T> {
272             #[inline]
273             fn deref_mut(&mut self) -> &mut Self::Target {
274                 &mut self.0
275             }
276         }
277     };
278 
279     ($ident:ident: $ty:ty) => {
280         impl std::ops::Deref for $ident {
281             type Target = $ty;
282 
283             #[inline]
284             fn deref(&self) -> &Self::Target {
285                 &self.0
286             }
287         }
288 
289         impl std::ops::DerefMut for $ident {
290             #[inline]
291             fn deref_mut(&mut self) -> &mut Self::Target {
292                 &mut self.0
293             }
294         }
295     };
296 }
297