teo_runtime/request/
local_values.rs

1use std::collections::BTreeMap;
2use std::fmt;
3use std::fmt::{Debug, Formatter};
4use std::sync::Arc;
5use history_box::HistoryBox;
6use maplit::btreemap;
7use teo_result::{Result, Error};
8use crate::Value;
9
10#[derive(Default, Clone)]
11pub struct LocalValues {
12    inner: Arc<Inner>,
13}
14
15#[derive(Default)]
16struct Inner {
17    map: HistoryBox<BTreeMap<String, HistoryBox<Value>>>,
18}
19
20impl LocalValues {
21
22    #[inline]
23    pub fn new() -> LocalValues {
24        Self {
25            inner: Arc::new(Inner {
26                map: HistoryBox::new_with(btreemap! {}),
27            })
28        }
29    }
30
31    fn map_mut(&self) -> &mut BTreeMap<String, HistoryBox<Value>> {
32        unsafe { self.inner.map.get_mut().unwrap() }
33    }
34
35    fn map_immut(&self) -> &BTreeMap<String, HistoryBox<Value>> {
36        unsafe { self.inner.map.get().unwrap() }
37    }
38
39    pub fn insert<T: 'static + Into<Value>>(&self, key: impl Into<String>, val: T) {
40        let key = key.into();
41        let contains = self.map_immut().contains_key(&key);
42        if contains {
43            self.map_mut().get_mut(&key).unwrap().set(val.into());
44        } else {
45            self.map_mut().insert(key, HistoryBox::new_with(val.into()));
46        }
47    }
48
49    pub fn get<'a, T>(&'a self, key: &str) -> Result<T> where T: 'a + TryFrom<&'a Value>, Error: From<T::Error> {
50        match self.map_immut().get(key) {
51            None => Err(Error::new(format!("value not found for key: {}", key))),
52            Some(v) => {
53                let v = T::try_from(v.get().unwrap())?;
54                Ok(v)
55            }
56        }
57    }
58
59    pub fn get_mut(&self, key: &str) -> Result<&mut Value> {
60        match self.map_immut().get(key) {
61            None => Err(Error::new(format!("value not found for key: {}", key))),
62            Some(v) => Ok(unsafe { v.get_mut() }.unwrap())
63        }
64    }
65
66    pub fn contains(&self, key: &str) -> bool {
67        self.map_immut().contains_key(key)
68    }
69
70    pub fn remove(&self, key: &str) {
71        self.map_mut().remove(key);
72    }
73
74    pub fn len(&self) -> usize {
75        self.map_immut().len()
76    }
77
78    pub fn clear(&self) {
79        self.map_mut().clear()
80    }
81}
82
83impl Debug for LocalValues {
84
85    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
86        let mut debug_struct = f.debug_struct("LocalValues");
87        for (k, v) in self.map_immut() {
88            debug_struct.field(&k, &v);
89        }
90        debug_struct.finish()
91    }
92}
93
94unsafe impl Send for LocalValues { }
95unsafe impl Sync for LocalValues { }