saphir/
extension.rs

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    /// The extension type was not found, the type name of the missing extension
18    /// is returned
19    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}