acme_core/specs/
store.rs

1/*
2    Appellation: stores <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5#[cfg(not(feature = "std"))]
6use alloc::collections::{btree_map, BTreeMap};
7use core::borrow::Borrow;
8#[cfg(feature = "std")]
9use std::collections::{btree_map, hash_map, BTreeMap, HashMap};
10
11pub trait Entry<'a> {
12    type Key;
13    type Value;
14
15    fn key(&self) -> &Self::Key;
16
17    fn or_insert(self, default: Self::Value) -> &'a mut Self::Value;
18}
19
20pub trait Get<Q> {
21    type Key: Borrow<Q>;
22    type Value;
23
24    fn get(&self, key: &Q) -> Option<&Self::Value>;
25}
26
27pub trait GetMut<Q>: Get<Q> {
28    fn get_mut(&mut self, key: &Q) -> Option<&mut Self::Value>;
29}
30
31impl<Q, K, V> Get<Q> for BTreeMap<K, V>
32where
33    K: Borrow<Q> + Ord,
34    Q: Ord,
35{
36    type Key = K;
37    type Value = V;
38
39    fn get(&self, key: &Q) -> Option<&Self::Value> {
40        BTreeMap::get(self, key)
41    }
42}
43
44pub trait Store<K, V> {
45    fn get(&self, key: &K) -> Option<&V>;
46
47    fn get_mut(&mut self, key: &K) -> Option<&mut V>;
48
49    fn insert(&mut self, key: K, value: V) -> Option<V>;
50
51    fn remove(&mut self, key: &K) -> Option<V>;
52}
53
54pub trait StoreExt<T>
55where
56    T: crate::id::Identifiable,
57{
58    type Store: Store<T::Id, T>;
59
60    fn store(&self) -> &Self::Store;
61
62    fn store_mut(&mut self) -> &mut Self::Store;
63
64    fn get(&self, item: T) -> Option<&T> {
65        Store::get(self.store(), item.id())
66    }
67
68    fn get_mut(&mut self, item: T) -> Option<&mut T> {
69        Store::get_mut(self.store_mut(), item.id())
70    }
71
72    fn insert(&mut self, item: T) -> Option<T> {
73        Store::insert(self.store_mut(), *item.id(), item)
74    }
75
76    fn remove(&mut self, item: T) -> Option<T> {
77        Store::remove(self.store_mut(), item.id())
78    }
79}
80
81impl<S, T> StoreExt<T> for S
82where
83    S: Store<T::Id, T>,
84    T: crate::id::Identifiable,
85{
86    type Store = S;
87
88    fn store(&self) -> &Self::Store {
89        self
90    }
91
92    fn store_mut(&mut self) -> &mut Self::Store {
93        self
94    }
95}
96
97pub trait Cache<K, V> {
98    fn get_or_insert_with<F>(&mut self, key: K, f: F) -> &mut V
99    where
100        F: FnOnce() -> V;
101}
102
103pub trait OrInsert<K, V> {
104    fn or_insert(&mut self, key: K, value: V) -> &mut V;
105}
106
107macro_rules! entry {
108    ($($prefix:ident)::* -> $call:ident($($arg:tt),*)) => {
109        $($prefix)::*::Entry::$call($($arg),*)
110    };
111
112}
113
114macro_rules! impl_entry {
115    ($($prefix:ident)::* where $($preds:tt)* ) => {
116
117        impl<'a, K, V> Entry<'a> for $($prefix)::*::Entry<'a, K, V> where $($preds)* {
118            type Key = K;
119            type Value = V;
120
121            fn key(&self) -> &Self::Key {
122                entry!($($prefix)::* -> key(self))
123            }
124
125            fn or_insert(self, default: Self::Value) -> &'a mut Self::Value {
126                entry!($($prefix)::* -> or_insert(self, default))
127            }
128        }
129
130    };
131
132}
133
134macro_rules! impl_store {
135    ($t:ty, where $($preds:tt)* ) => {
136
137        impl<K, V> Store<K, V> for $t where $($preds)* {
138            fn get(&self, key: &K) -> Option<&V> {
139                <$t>::get(self, &key)
140            }
141
142            fn get_mut(&mut self, key: &K) -> Option<&mut V> {
143                <$t>::get_mut(self, &key)
144            }
145
146            fn insert(&mut self, key: K, value: V) -> Option<V> {
147                <$t>::insert(self, key, value)
148            }
149
150            fn remove(&mut self, key: &K) -> Option<V> {
151                <$t>::remove(self, &key)
152            }
153        }
154
155    };
156}
157
158impl_entry!(btree_map where K: Ord);
159#[cfg(feature = "std")]
160impl_entry!(hash_map where K: Eq + core::hash::Hash);
161impl_store!(BTreeMap<K, V>, where K: Ord);
162#[cfg(feature = "std")]
163impl_store!(HashMap<K, V>, where K: Eq + core::hash::Hash);