simple_api/
context.rs

1use std::any::Any;
2use std::collections::HashMap;
3use std::sync::Arc;
4
5use crate::{
6    session::{Session, SessionProvider},
7    types::{State, ViewPathArgs},
8};
9
10pub struct AnyMap(HashMap<String, Box<dyn Any + Send + Sync>>);
11
12impl AnyMap {
13    pub fn get<T: 'static + Send>(&self, key: &str) -> Option<&T> {
14        self.0.get(key).and_then(|v| v.downcast_ref::<T>())
15    }
16
17    pub fn set<T: 'static + Send + Sync>(&mut self, key: &str, value: T) {
18        self.0.insert(key.to_string(), Box::new(value));
19    }
20
21    pub fn get_mut<T: 'static + Send>(&mut self, key: &str) -> Option<&mut T> {
22        self.0.get_mut(key).and_then(|v| v.downcast_mut::<T>())
23    }
24}
25
26pub struct Context {
27    pub any_map: AnyMap, // like flask g
28    pub session: Option<Box<dyn Session>>,
29    pub session_provider: Option<Arc<dyn SessionProvider>>,
30    pub state: State,
31    pub view_args: Option<ViewPathArgs>, // 只有在route匹配失败时,才会为None。
32}
33
34impl Context {
35    pub fn new(
36        session_provider: Option<Arc<dyn SessionProvider>>,
37        state: State,
38        view_args: Option<ViewPathArgs>,
39    ) -> Self {
40        Context {
41            any_map: AnyMap(HashMap::new()),
42            session: None,
43            session_provider,
44            state,
45            view_args,
46        }
47    }
48
49    pub fn get_state<T: 'static + Send + Sync>(&self) -> anyhow::Result<Arc<T>> {
50        self.state
51            .clone()
52            .downcast::<T>()
53            .map_err(|_| anyhow::anyhow!("cast failed"))
54    }
55}