teo_runtime/request/
local_values.rs1use 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 { }