panopticon_core/data/
store.rs1use crate::imports::*;
2
3#[derive(Debug, Clone)]
18pub struct Store<T = StoreEntry> {
19 entries: HashMap<String, T>,
20}
21
22impl Default for Store<StoreEntry> {
23 fn default() -> Self {
24 Store::new()
25 }
26}
27
28impl<T> Store<T> {
29 pub fn new() -> Self {
31 Store::<T> {
32 entries: HashMap::new(),
33 }
34 }
35
36 pub fn get<N: AsRef<str>>(&self, name: N) -> Result<&T, StoreError> {
39 let name = name.as_ref();
40 self.entries
41 .get(name)
42 .ok_or_else(|| StoreError::EntryNotFound(name.into()))
43 }
44
45 pub fn insert<N: Into<String>>(&mut self, name: N, entry: T) -> Result<(), StoreError> {
48 let name = name.into();
49 if self.entries.contains_key(&name) {
50 return Err(StoreError::EntryAlreadyExists(name));
51 }
52 self.entries.insert(name, entry);
53 Ok(())
54 }
55
56 pub fn insert_or_replace<N: Into<String>>(&mut self, name: N, entry: T) {
60 self.entries.insert(name.into(), entry);
61 }
62
63 pub fn merge(&mut self, prefix_opt: Option<&str>, other: Store<T>) -> Result<(), StoreError> {
67 let key_prefix = match prefix_opt {
68 Some(prefix) => format!("{}.", prefix),
69 None => String::new(),
70 };
71 for (key, value) in other.entries {
72 let key = format!("{}{}", key_prefix, key);
73 if self.entries.contains_key(&key) {
74 return Err(StoreError::EntryAlreadyExists(key));
75 }
76 self.entries.insert(key, value);
77 }
78 Ok(())
79 }
80
81 pub fn keys(&self) -> impl Iterator<Item = &String> {
83 self.entries.keys()
84 }
85
86 pub fn iter(&self) -> impl Iterator<Item = (&String, &T)> {
88 self.entries.iter()
89 }
90}
91
92impl Store<StoreEntry> {
93 pub fn define_var<N: Into<String>, V: Into<Value>>(
97 &mut self,
98 name: N,
99 value: V,
100 ) -> Result<(), StoreError> {
101 let name = name.into();
102 if self.entries.contains_key(&name) {
103 return Err(StoreError::EntryAlreadyExists(name));
104 }
105 let value = value.into();
106 let ty = value.get_type();
107 self.entries.insert(name, StoreEntry::Var { value, ty });
108 Ok(())
109 }
110
111 pub fn define_array<N: Into<String>>(
114 &mut self,
115 name: N,
116 ) -> Result<ArrayHandle<'_, StoreEntry>, StoreError> {
117 let name = name.into();
118 if self.entries.contains_key(&name) {
119 return Err(StoreError::EntryAlreadyExists(name));
120 }
121 self.entries
122 .insert(name.clone(), StoreEntry::Array(Vec::new()));
123 let data = match self.entries.get_mut(&name) {
124 Some(StoreEntry::Array(arr)) => arr,
125 _ => unreachable!(),
126 };
127 Ok(ArrayHandle::new(name, data))
128 }
129
130 pub fn define_map<N: Into<String>>(
133 &mut self,
134 name: N,
135 ) -> Result<MapHandle<'_, StoreEntry>, StoreError> {
136 let name = name.into();
137 if self.entries.contains_key(&name) {
138 return Err(StoreError::EntryAlreadyExists(name));
139 }
140 self.entries
141 .insert(name.clone(), StoreEntry::Map(HashMap::new()));
142 let data = match self.entries.get_mut(&name) {
143 Some(StoreEntry::Map(map)) => map,
144 _ => unreachable!(),
145 };
146 Ok(MapHandle::new(name, data))
147 }
148
149 pub fn with_array<N: Into<String>, F>(&mut self, name: N, body: F) -> Result<(), StoreError>
154 where
155 F: FnOnce(&mut ArrayHandle<StoreEntry>) -> Result<(), StoreError>,
156 {
157 let name = name.into();
158 let mut arr_handle = self.define_array(name)?;
159 body(&mut arr_handle)
160 }
161 pub fn with_map<N: Into<String>, F>(&mut self, name: N, body: F) -> Result<(), StoreError>
164 where
165 F: FnOnce(&mut MapHandle<StoreEntry>) -> Result<(), StoreError>,
166 {
167 let name = name.into();
168 let mut map_handle = self.define_map(name)?;
169 body(&mut map_handle)
170 }
171}
172
173impl<T> IntoIterator for Store<T> {
174 type Item = (String, T);
175 type IntoIter = std::collections::hash_map::IntoIter<String, T>;
176
177 fn into_iter(self) -> Self::IntoIter {
178 self.entries.into_iter()
179 }
180}