rsdiff_core/stores/
specs.rs

1/*
2    Appellation: stores <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use 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);