xitca_web/handler/types/
extension.rs

1//! type extractor for value from [Extensions] and itself.
2
3use core::{fmt, ops::Deref};
4
5use crate::{
6    context::WebContext,
7    error::{Error, ExtensionNotFound},
8    handler::FromRequest,
9    http::Extensions,
10};
11
12/// Extract immutable reference of element stored inside [Extensions]
13#[derive(Debug)]
14pub struct ExtensionRef<'a, T>(pub &'a T);
15
16impl<T> Deref for ExtensionRef<'_, T> {
17    type Target = T;
18
19    fn deref(&self) -> &Self::Target {
20        self.0
21    }
22}
23
24impl<'a, 'r, C, B, T> FromRequest<'a, WebContext<'r, C, B>> for ExtensionRef<'a, T>
25where
26    T: Send + Sync + 'static,
27{
28    type Type<'b> = ExtensionRef<'b, T>;
29    type Error = Error;
30
31    #[inline]
32    async fn from_request(ctx: &'a WebContext<'r, C, B>) -> Result<Self, Self::Error> {
33        ctx.req()
34            .extensions()
35            .get::<T>()
36            .map(ExtensionRef)
37            .ok_or_else(|| Error::from_service(ExtensionNotFound::from_type::<T>()))
38    }
39}
40
41/// Extract owned type stored inside [Extensions]
42pub struct ExtensionOwn<T>(pub T);
43
44impl<T: fmt::Debug> fmt::Debug for ExtensionOwn<T> {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        write!(f, "ExtensionOwn({:?})", self.0)
47    }
48}
49
50impl<T> Deref for ExtensionOwn<T> {
51    type Target = T;
52
53    fn deref(&self) -> &Self::Target {
54        &self.0
55    }
56}
57
58impl<'a, 'r, C, B, T> FromRequest<'a, WebContext<'r, C, B>> for ExtensionOwn<T>
59where
60    T: Send + Sync + Clone + 'static,
61{
62    type Type<'b> = ExtensionOwn<T>;
63    type Error = Error;
64
65    #[inline]
66    async fn from_request(ctx: &'a WebContext<'r, C, B>) -> Result<Self, Self::Error> {
67        ctx.req()
68            .extensions()
69            .get::<T>()
70            .map(|ext| ExtensionOwn(ext.clone()))
71            .ok_or_else(|| Error::from_service(ExtensionNotFound::from_type::<T>()))
72    }
73}
74
75/// Extract immutable reference of the [Extensions].
76pub struct ExtensionsRef<'a>(pub &'a Extensions);
77
78impl Deref for ExtensionsRef<'_> {
79    type Target = Extensions;
80
81    fn deref(&self) -> &Self::Target {
82        self.0
83    }
84}
85
86impl<'a, 'r, C, B> FromRequest<'a, WebContext<'r, C, B>> for ExtensionsRef<'a> {
87    type Type<'b> = ExtensionsRef<'b>;
88    type Error = Error;
89
90    #[inline]
91    async fn from_request(ctx: &'a WebContext<'r, C, B>) -> Result<Self, Self::Error> {
92        Ok(ExtensionsRef(ctx.req().extensions()))
93    }
94}