1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
    Appellation: stores <module>
    Contrib: FL03 <jo3mccain@icloud.com>
*/
use core::borrow::Borrow;
use std::collections::{BTreeMap, HashMap};

pub trait Get<Q> {
    type Key: Borrow<Q>;
    type Value;

    fn get(&self, key: &Q) -> Option<&Self::Value>;
}

pub trait GetMut<Q>: Get<Q> {
    fn get_mut(&mut self, key: &Q) -> Option<&mut Self::Value>;
}

impl<Q, K, V> Get<Q> for BTreeMap<K, V>
where
    K: Borrow<Q> + Ord,
    Q: Ord,
{
    type Key = K;
    type Value = V;

    fn get(&self, key: &Q) -> Option<&Self::Value> {
        BTreeMap::get(self, key)
    }
}

pub trait Store<K, V> {
    fn get(&self, key: &K) -> Option<&V>;

    fn get_mut(&mut self, key: &K) -> Option<&mut V>;

    fn insert(&mut self, key: K, value: V) -> Option<V>;

    fn remove(&mut self, key: &K) -> Option<V>;
}

pub trait Cache<K, V> {
    fn get_or_insert_with<F>(&mut self, key: K, f: F) -> &mut V
    where
        F: FnOnce() -> V;
}

pub trait OrInsert<K, V> {
    fn or_insert(&mut self, key: K, value: V) -> &mut V;
}

macro_rules! impl_store {
    ($t:ty, where $($preds:tt)* ) => {

        impl<K, V> Store<K, V> for $t where $($preds)* {
            fn get(&self, key: &K) -> Option<&V> {
                <$t>::get(self, &key)
            }

            fn get_mut(&mut self, key: &K) -> Option<&mut V> {
                <$t>::get_mut(self, &key)
            }

            fn insert(&mut self, key: K, value: V) -> Option<V> {
                <$t>::insert(self, key, value)
            }

            fn remove(&mut self, key: &K) -> Option<V> {
                <$t>::remove(self, &key)
            }
        }

    };
}

impl_store!(BTreeMap<K, V>, where K: Ord);
impl_store!(HashMap<K, V>, where K: Eq + std::hash::Hash);