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