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