spring_web/
extractor.rs

1pub use axum::extract::*;
2
3use crate::error::{Result, WebError};
4use crate::AppState;
5use anyhow::Context;
6use axum::http::request::Parts;
7use spring::config::{ConfigRegistry, Configurable};
8use spring::plugin::ComponentRegistry;
9use std::ops::{Deref, DerefMut};
10use std::result::Result as StdResult;
11
12/// Extending the functionality of RequestParts
13pub trait RequestPartsExt {
14    /// get AppState
15    fn get_app_state(&self) -> &AppState;
16
17    /// get Component
18    fn get_component<T: Clone + Send + Sync + 'static>(&self) -> Result<T>;
19
20    /// get Config
21    fn get_config<T: serde::de::DeserializeOwned + Configurable>(&self) -> Result<T>;
22}
23
24impl RequestPartsExt for Parts {
25    fn get_app_state(&self) -> &AppState {
26        self.extensions
27            .get::<AppState>()
28            .expect("extract app state from extension failed")
29    }
30
31    fn get_component<T: Clone + Send + Sync + 'static>(&self) -> Result<T> {
32        Ok(self
33            .get_app_state()
34            .app
35            .try_get_component()
36            .context("get_component failed")?)
37    }
38
39    fn get_config<T: serde::de::DeserializeOwned + Configurable>(&self) -> Result<T> {
40        self.get_app_state()
41            .app
42            .get_config::<T>()
43            .map_err(|e| WebError::ConfigDeserializeErr(std::any::type_name::<T>(), Box::new(e)))
44    }
45}
46
47/// Extract the components registered by the plugin from AppState
48pub struct Component<T: Clone>(pub T);
49
50impl<T, S> FromRequestParts<S> for Component<T>
51where
52    T: Clone + Send + Sync + 'static,
53    S: Sync,
54{
55    type Rejection = WebError;
56
57    async fn from_request_parts(parts: &mut Parts, _s: &S) -> StdResult<Self, Self::Rejection> {
58        parts.get_component::<T>().map(|c| Component(c))
59    }
60}
61
62impl<T: Clone> Deref for Component<T> {
63    type Target = T;
64
65    fn deref(&self) -> &Self::Target {
66        &self.0
67    }
68}
69
70impl<T: Clone> DerefMut for Component<T> {
71    fn deref_mut(&mut self) -> &mut Self::Target {
72        &mut self.0
73    }
74}
75
76pub struct Config<T>(pub T)
77where
78    T: serde::de::DeserializeOwned + Configurable;
79
80impl<T, S> FromRequestParts<S> for Config<T>
81where
82    T: serde::de::DeserializeOwned + Configurable,
83    S: Sync,
84{
85    type Rejection = WebError;
86
87    async fn from_request_parts(parts: &mut Parts, _s: &S) -> StdResult<Self, Self::Rejection> {
88        parts.get_config().map(|c| Config(c))
89    }
90}
91
92impl<T> Deref for Config<T>
93where
94    T: serde::de::DeserializeOwned + Configurable,
95{
96    type Target = T;
97
98    fn deref(&self) -> &Self::Target {
99        &self.0
100    }
101}
102
103impl<T> DerefMut for Config<T>
104where
105    T: serde::de::DeserializeOwned + Configurable,
106{
107    fn deref_mut(&mut self) -> &mut Self::Target {
108        &mut self.0
109    }
110}