vertigo/computed/
auto_map.rs1use std::fmt::Debug;
2use std::{hash::Hash, rc::Rc};
3
4use crate::computed::struct_mut::HashMapMut;
5
6type CreateType<K, V> = Box<dyn Fn(&AutoMap<K, V>, &K) -> V>;
7
8fn get_unique_id() -> u64 {
9 use std::sync::atomic::{AtomicU64, Ordering};
10 static COUNTER: AtomicU64 = AtomicU64::new(1);
11 COUNTER.fetch_add(1, Ordering::Relaxed)
12}
13
14#[derive(Clone)]
26pub struct AutoMap<K, V> {
27 id: u64,
28 create: Rc<CreateType<K, V>>,
29 values: Rc<HashMapMut<K, V>>,
30}
31
32impl<K, V> Debug for AutoMap<K, V> {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct("AutoMap").finish()
35 }
36}
37
38impl<K, V> PartialEq for AutoMap<K, V> {
39 fn eq(&self, other: &Self) -> bool {
40 self.id == other.id
41 }
42}
43
44impl<K: Eq + Hash + Clone, V: Clone> AutoMap<K, V> {
45 pub fn new<C: Fn(&AutoMap<K, V>, &K) -> V + 'static>(create: C) -> AutoMap<K, V> {
46 AutoMap {
47 id: get_unique_id(),
48 create: Rc::new(Box::new(create)),
49 values: Rc::new(HashMapMut::new()),
50 }
51 }
52
53 pub fn get(&self, key: &K) -> V {
54 let item: Option<V> = self.values.get(key);
55
56 if let Some(item) = item {
57 return item;
58 }
59
60 let new_item = {
61 let create = &self.create;
62 create(self, key)
63 };
64
65 self.values.insert(key.clone(), new_item.clone());
66
67 new_item
68 }
69}