1#![doc = include_str!("../readme.md")]
2use std::{
3 any::{Any, TypeId},
4 collections::{HashMap, HashSet},
5 fmt::Debug,
6 ops::{Deref, DerefMut},
7 sync::Arc,
8};
9
10#[derive(Debug, Clone)]
11pub struct RefMeta(pub Arc<Metamap>);
12
13impl RefMeta {
14 pub fn new(meta: Metamap) -> Self {
15 RefMeta(Arc::new(meta))
16 }
17}
18
19impl Deref for RefMeta {
20 type Target = Metamap;
21
22 fn deref(&self) -> &Self::Target {
23 &self.0
24 }
25}
26
27impl DerefMut for RefMeta {
28 fn deref_mut(&mut self) -> &mut Self::Target {
29 Arc::get_mut(&mut self.0).expect("Cannot mutate a shared reference")
30 }
31}
32
33#[derive(Default)]
38pub struct Metamap {
39 map: HashMap<String, Box<dyn Any + Send + Sync>>,
40 extend: Option<RefMeta>,
41}
42
43impl Debug for Metamap {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 let mut keys = self.map.keys().collect::<HashSet<&String>>();
46 if let Some(p) = &self.extend {
47 let keys2 = p.0.map.keys().collect::<HashSet<&String>>();
48 keys.extend(keys2);
49 }
50 f.debug_struct("Metamap").field("keys", &keys.iter()).finish()
51 }
52}
53
54impl Metamap {
55 pub fn new() -> Self {
56 Metamap { map: HashMap::new(), extend: None }
57 }
58
59 pub fn inner(&self) -> &HashMap<String, Box<dyn Any + Send + Sync>> {
60 &self.map
61 }
62
63 #[inline]
64 pub fn with_capacity(capacity: usize) -> Self {
65 Metamap { map: HashMap::with_capacity(capacity), extend: None }
66 }
67
68 pub fn capacity(&self) -> usize {
69 self.map.capacity()
70 }
71
72 pub fn set<V: Any + Send + Sync>(&mut self, key: impl Into<String>, value: V) -> &mut Self {
73 self.map.insert(key.into(), Box::new(value));
74 self
75 }
76
77 pub fn get<V: Any + Send + Sync>(&self, key: impl Into<String>) -> Option<&V> {
78 let key: String = key.into();
79 let t = self.map.get(&key).and_then(|v| v.downcast_ref::<V>());
80 let r = match t {
81 Some(v) => Some(v),
82 None => match &self.extend {
83 Some(p) => p.get::<V>(key),
84 None => None,
85 },
86 };
87 r
88 }
89
90 pub fn get_mut<V: Any + Send + Sync>(&mut self, key: impl Into<String>) -> Option<&mut V> {
91 let key = key.into();
92 let t = self.map.get_mut(&key).and_then(|v| v.downcast_mut::<V>());
93 match t {
94 Some(v) => Some(v),
95 None => None,
96 }
97 }
98
99 pub fn set_data<V: Any + Send + Sync>(&mut self, value: V) -> &mut Self {
100 self.set(type_key::<V>(), value)
101 }
102
103 pub fn get_data<V: Any + Send + Sync>(&self) -> Option<&V> {
104 self.get(type_key::<V>())
105 }
106
107 pub fn get_mut_data<V: Any + Send + Sync>(&mut self) -> Option<&mut V> {
108 self.get_mut(type_key::<V>())
109 }
110
111 pub fn take<V: Any + Send + Sync>(&mut self, key: impl Into<String>) -> Option<V> {
112 let key: String = key.into();
113 let t = self.map.remove(&key).and_then(|v| v.downcast::<V>().ok());
114 t.map(|v| *v)
115 }
116
117 pub fn take_data<V: Any + Send + Sync>(&mut self) -> Option<V> {
118 self.take(type_key::<V>())
119 }
120
121 pub fn contains(&self, key: impl Into<String>) -> bool {
122 self.map.contains_key(&key.into())
123 }
124
125 pub fn contains_value<V: Any + Send + Sync>(&self) -> bool {
126 self.contains(type_key::<V>())
127 }
128
129 pub fn remove(&mut self, key: impl Into<String>) -> Option<Box<dyn Any + Send + Sync>> {
130 let key: String = key.into();
131 let t = self.map.remove(&key);
132 match t {
133 Some(v) => Some(v),
134 None => None,
135 }
136 }
137
138 pub fn remove_value<V: Any + Send + Sync>(&mut self) -> Option<Box<dyn Any + Send + Sync>> {
139 self.remove(type_key::<V>())
140 }
141
142 pub fn merge(&mut self, meta: Metamap) -> &mut Self {
143 for (k, v) in meta.map {
144 self.map.insert(k, v);
145 }
146 self
147 }
148
149 pub fn extend(&mut self, ref_meta: RefMeta) -> &mut Self {
150 self.extend = Some(ref_meta);
151 self
152 }
153
154 pub fn iter(&self) -> std::collections::hash_map::Iter<String, Box<dyn Any + Send + Sync>> {
155 self.map.iter()
156 }
157
158 pub fn iter_mut(&mut self) -> std::collections::hash_map::IterMut<String, Box<dyn Any + Send + Sync>> {
159 self.map.iter_mut()
160 }
161
162 pub fn keys(&self) -> Vec<String> {
163 let mut keys = self.map.keys().collect::<HashSet<&String>>();
164 if let Some(p) = &self.extend {
165 let keys2 = p.map.keys().collect::<HashSet<&String>>();
166 keys.extend(keys2);
167 }
168 keys.iter().map(|k| k.to_string()).collect()
169 }
170
171 pub fn len(&self) -> usize {
172 self.map.len()
173 }
174
175 pub fn is_empty(&self) -> bool {
176 self.map.is_empty()
177 }
178
179 pub fn clear(&mut self) {
180 self.map.clear();
181 }
182}
183
184pub fn type_key<T: 'static>() -> String {
185 format!("{:?}", TypeId::of::<T>())
186}
187
188#[cfg(test)]
189mod tests {
190 use super::*;
191
192 #[test]
193 fn test_metadata() {
194 #[derive(Debug, PartialEq, Eq)]
195 enum TestEnum {
196 A,
197 B,
198 }
199
200 #[derive(Debug, PartialEq, Eq)]
201 struct TestData {
202 pub name: String,
203 }
204
205 #[derive(Debug, PartialEq, Eq)]
206 struct TupleData(i32, String);
207
208 let mut meta = Metamap::new();
209 meta.set_data(TestEnum::A);
210 meta.set_data(TestData { name: "test".to_string() });
211 meta.set_data(TupleData(1, "tuple".to_string()));
212
213 assert_eq!(*meta.get_data::<TestEnum>().unwrap(), TestEnum::A);
214 assert_ne!(*meta.get_data::<TestEnum>().unwrap(), TestEnum::B);
215 assert_eq!(*meta.get_data::<TestData>().unwrap(), TestData { name: "test".to_string() });
216 assert_eq!(*meta.get_data::<TupleData>().unwrap(), TupleData(1, "tuple".to_string()));
217
218 assert_eq!(meta.take_data::<TestData>().unwrap(), TestData { name: "test".to_string() });
219 assert_eq!(meta.take_data::<TestEnum>().unwrap(), TestEnum::A);
220 assert_eq!(meta.take_data::<TupleData>().unwrap(), TupleData(1, "tuple".to_string()));
221
222 assert!(meta.get_data::<TestData>().is_none());
223 assert!(meta.get_data::<TestEnum>().is_none());
224 assert!(meta.get_data::<TupleData>().is_none());
225 }
226
227 #[test]
228 fn test_meta() {
229 let mut meta = Metamap::new();
230 meta.set("a", 1);
231 meta.set("b", "2");
232 meta.set("c", 3.0);
233 meta.set("d", "4".to_string());
234 meta.set("e", vec![1, 2, 3]);
235 meta.set("f", vec!["1", "2", "3"]);
236 meta.set("g", vec![1.0, 2.0, 3.0]);
237 meta.set("h", vec!["1".to_string(), "2".to_string(), "3".to_string()]);
238 meta.set("i", vec![vec![1, 2], vec![3, 4]]);
239 meta.set("j", vec![vec!["1", "2"], vec!["3", "4"]]);
240 meta.set("k", vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
241 meta.set("l", vec![vec!["1".to_string(), "2".to_string()], vec!["3".to_string(), "4".to_string()]]);
242
243 assert_eq!(*meta.get::<i32>("a").unwrap(), 1);
244 assert_eq!(*meta.get::<&str>("b").unwrap(), "2");
245 assert_eq!(*meta.get::<f64>("c").unwrap(), 3.0);
246 assert_eq!(*meta.get::<String>("d").unwrap(), "4".to_string());
247 assert_eq!(*meta.get::<Vec<i32>>("e").unwrap(), vec![1, 2, 3]);
248 assert_eq!(*meta.get::<Vec<&str>>("f").unwrap(), vec!["1", "2", "3"]);
249 assert_eq!(*meta.get::<Vec<f64>>("g").unwrap(), vec![1.0, 2.0, 3.0]);
250 assert_eq!(*meta.get::<Vec<String>>("h").unwrap(), vec!["1".to_string(), "2".to_string(), "3".to_string()]);
251 assert_eq!(*meta.get::<Vec<Vec<i32>>>("i").unwrap(), vec![vec![1, 2], vec![3, 4]]);
252 assert_eq!(*meta.get::<Vec<Vec<&str>>>("j").unwrap(), vec![vec!["1", "2"], vec!["3", "4"]]);
253 }
254
255 #[test]
256 fn test_mut_meta() {
257 let mut meta = Metamap::new();
258 meta.set("a", 1);
259 meta.set("b", "2");
260 meta.set("c", 3.0);
261 meta.set("d", "4".to_string());
262 meta.set("e", vec![1, 2, 3]);
263 meta.set("f", vec!["1", "2", "3"]);
264 meta.set("g", vec![1.0, 2.0, 3.0]);
265 meta.set("h", vec!["1".to_string(), "2".to_string(), "3".to_string()]);
266 meta.set("i", vec![vec![1, 2], vec![3, 4]]);
267 meta.set("j", vec![vec!["1", "2"], vec!["3", "4"]]);
268 meta.set("k", vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
269 meta.set("l", vec![vec!["1".to_string(), "2".to_string()], vec!["3".to_string(), "4".to_string()]]);
270
271 *meta.get_mut::<i32>("a").unwrap() = 2;
272 *meta.get_mut::<&str>("b").unwrap() = "3";
273 *meta.get_mut::<f64>("c").unwrap() = 4.0;
274 *meta.get_mut::<String>("d").unwrap() = "5".to_string();
275 *meta.get_mut::<Vec<i32>>("e").unwrap() = vec![2, 3, 4];
276 *meta.get_mut::<Vec<&str>>("f").unwrap() = vec!["2", "3", "4"];
277 *meta.get_mut::<Vec<f64>>("g").unwrap() = vec![2.0, 3.0, 4.0];
278 *meta.get_mut::<Vec<String>>("h").unwrap() = vec!["2".to_string(), "3".to_string(), "4".to_string()];
279 *meta.get_mut::<Vec<Vec<i32>>>("i").unwrap() = vec![vec![2, 3], vec![4, 5]];
280 *meta.get_mut::<Vec<Vec<&str>>>("j").unwrap() = vec![vec!["2", "3"], vec!["4", "5"]];
281
282 assert_eq!(*meta.get::<i32>("a").unwrap(), 2);
283 assert_eq!(*meta.get::<&str>("b").unwrap(), "3");
284 assert_eq!(*meta.get::<f64>("c").unwrap(), 4.0);
285 assert_eq!(*meta.get::<String>("d").unwrap(), "5".to_string());
286 assert_eq!(*meta.get::<Vec<i32>>("e").unwrap(), vec![2, 3, 4]);
287 assert_eq!(*meta.get::<Vec<&str>>("f").unwrap(), vec!["2", "3", "4"]);
288 assert_eq!(*meta.get::<Vec<f64>>("g").unwrap(), vec![2.0, 3.0, 4.0]);
289 assert_eq!(*meta.get::<Vec<String>>("h").unwrap(), vec!["2".to_string(), "3".to_string(), "4".to_string()]);
290 assert_eq!(*meta.get::<Vec<Vec<i32>>>("i").unwrap(), vec![vec![2, 3], vec![4, 5]]);
291 assert_eq!(*meta.get::<Vec<Vec<&str>>>("j").unwrap(), vec![vec!["2", "3"], vec!["4", "5"]]);
292 }
293
294 #[test]
295 fn test_meta_merge() {
296 let mut meta1 = Metamap::new();
297 meta1.set("a", 1);
298 meta1.set("b", "2");
299 meta1.set("c", 3.0);
300 meta1.set("d", "4".to_string());
301 meta1.set("e", vec![1, 2, 3]);
302 meta1.set("f", vec!["1", "2", "3"]);
303 meta1.set("g", vec![1.0, 2.0, 3.0]);
304 meta1.set("h", vec!["1".to_string(), "2".to_string(), "3".to_string()]);
305 meta1.set("i", vec![vec![1, 2], vec![3, 4]]);
306 meta1.set("j", vec![vec!["1", "2"], vec!["3", "4"]]);
307 meta1.set("k", vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
308 meta1.set("l", vec![vec!["1".to_string(), "2".to_string()], vec!["3".to_string(), "4".to_string()]]);
309
310 let mut meta2 = Metamap::new();
311 meta2.set("e", vec![2, 3, 4]);
312 meta2.set("f", vec!["2", "3", "4"]);
313 meta2.set("g", vec![2.0, 3.0, 4.0]);
314 meta2.set("h", vec!["2".to_string(), "3".to_string(), "4".to_string()]);
315 meta2.set("i", vec![vec![2, 3], vec![4, 5]]);
316 meta2.set("j", vec![vec!["2", "3"], vec!["4", "5"]]);
317
318 meta1.merge(meta2);
319
320 assert_eq!(*meta1.get::<i32>("a").unwrap(), 1);
321 assert_eq!(*meta1.get::<&str>("b").unwrap(), "2");
322 assert_eq!(*meta1.get::<f64>("c").unwrap(), 3.0);
323 assert_eq!(*meta1.get::<String>("d").unwrap(), "4".to_string());
324 assert_eq!(*meta1.get::<Vec<i32>>("e").unwrap(), vec![2, 3, 4]);
325 assert_eq!(*meta1.get::<Vec<&str>>("f").unwrap(), vec!["2", "3", "4"]);
326 assert_eq!(*meta1.get::<Vec<f64>>("g").unwrap(), vec![2.0, 3.0, 4.0]);
327 assert_eq!(*meta1.get::<Vec<String>>("h").unwrap(), vec!["2".to_string(), "3".to_string(), "4".to_string()]);
328 assert_eq!(*meta1.get::<Vec<Vec<i32>>>("i").unwrap(), vec![vec![2, 3], vec![4, 5]]);
329 assert_eq!(*meta1.get::<Vec<Vec<&str>>>("j").unwrap(), vec![vec!["2", "3"], vec!["4", "5"]]);
330 }
331
332 #[test]
333 fn test_meta_extend() {
334 let mut meta1 = Metamap::new();
335 meta1.set("a", 1);
336 meta1.set("b", "2");
337 meta1.set("c", 3.0);
338 meta1.set("d", "4".to_string());
339 meta1.set("e", vec![1, 2, 3]);
340 meta1.set("f", vec!["1", "2", "3"]);
341 meta1.set("g", vec![1.0, 2.0, 3.0]);
342
343 let mut meta2 = Metamap::new();
344 meta2.set("e", vec![2, 3, 4]);
345 meta2.set("i", vec![vec![2, 3], vec![4, 5]]);
346 meta2.set("j", vec![vec!["2", "3"], vec!["4", "5"]]);
347
348 meta1.extend(RefMeta::new(meta2));
349
350 assert_eq!(*meta1.get::<i32>("a").unwrap(), 1);
351 assert_eq!(*meta1.get::<&str>("b").unwrap(), "2");
352 assert_eq!(*meta1.get::<f64>("c").unwrap(), 3.0);
353 assert_eq!(*meta1.get::<String>("d").unwrap(), "4".to_string());
354 assert_eq!(*meta1.get::<Vec<i32>>("e").unwrap(), vec![1, 2, 3]);
355 assert_eq!(*meta1.get::<Vec<&str>>("f").unwrap(), vec!["1", "2", "3"]);
356 assert_eq!(*meta1.get::<Vec<f64>>("g").unwrap(), vec![1.0, 2.0, 3.0]);
357 assert_eq!(*meta1.get::<Vec<Vec<i32>>>("i").unwrap(), vec![vec![2, 3], vec![4, 5]]);
358 assert_eq!(*meta1.get::<Vec<Vec<&str>>>("j").unwrap(), vec![vec!["2", "3"], vec!["4", "5"]]);
359 }
360}