1use crate::{
2 http_context::HttpContext,
3 request::{FromRequest, Request},
4 responder::Responder,
5 response::Builder,
6};
7use std::{
8 borrow::{Borrow, BorrowMut},
9 ops::{Deref, DerefMut},
10};
11
12use crate::{body::Body, prelude::Bytes};
13pub use http::Extensions;
14
15#[derive(Debug)]
16pub enum ExtError {
17 MissingExtension(&'static str),
20}
21
22impl Responder for ExtError {
23 fn respond_with_builder(self, builder: Builder, _ctx: &HttpContext) -> Builder {
24 debug!("Missing extension of type: {}", std::any::type_name::<Self>());
25 builder.status(500)
26 }
27}
28
29pub struct Ext<T>(pub T);
30
31impl<T> Ext<T> {
32 pub fn into_inner(self) -> T {
33 self.0
34 }
35}
36
37impl<T> Deref for Ext<T> {
38 type Target = T;
39
40 fn deref(&self) -> &Self::Target {
41 &self.0
42 }
43}
44
45impl<T> DerefMut for Ext<T> {
46 fn deref_mut(&mut self) -> &mut Self::Target {
47 &mut self.0
48 }
49}
50
51impl<T> AsRef<T> for Ext<T> {
52 fn as_ref(&self) -> &T {
53 &self.0
54 }
55}
56
57impl<T> AsMut<T> for Ext<T> {
58 fn as_mut(&mut self) -> &mut T {
59 &mut self.0
60 }
61}
62
63impl<T> Borrow<T> for Ext<T> {
64 fn borrow(&self) -> &T {
65 &self.0
66 }
67}
68
69impl<T> BorrowMut<T> for Ext<T> {
70 fn borrow_mut(&mut self) -> &mut T {
71 &mut self.0
72 }
73}
74
75impl<T: Send + Sync + 'static> Responder for Ext<T> {
76 fn respond_with_builder(self, builder: Builder, _ctx: &HttpContext) -> Builder {
77 builder.extension(self.into_inner())
78 }
79}
80
81impl<T> FromRequest for Ext<T>
82where
83 T: Send + Sync + 'static,
84{
85 type Err = ExtError;
86 type Fut = futures::future::Ready<Result<Self, Self::Err>>;
87
88 fn from_request(req: &mut Request) -> Self::Fut {
89 futures::future::ready(
90 req.extensions_mut()
91 .remove::<T>()
92 .ok_or_else(|| ExtError::MissingExtension(std::any::type_name::<T>()))
93 .map(Ext),
94 )
95 }
96}
97
98impl FromRequest for Extensions {
99 type Err = ();
100 type Fut = futures::future::Ready<Result<Self, Self::Err>>;
101
102 fn from_request(req: &mut Request<Body<Bytes>>) -> Self::Fut {
103 futures::future::ready(Ok(std::mem::take(req.extensions_mut())))
104 }
105}