1#[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);