scsys_traits/cont/
entry.rs

1/*
2    appellation: entry <module>
3    authors: @FL03
4*/
5
6/// The [`Entry`] trait seeks to establish a common interface for all elements within a
7/// so-called _keyed_ container; i.e. on in which elements can be accessed by any type of key.
8pub trait Entry<'a> {
9    type Key;
10    type Value;
11    /// returns a reference to the key of the entry.
12    fn key(&self) -> &Self::Key;
13    /// if the entry does not exist, insert the provided value and return a mutable reference
14    /// to it
15    fn or_insert(self, default: Self::Value) -> &'a mut Self::Value;
16    /// if the entry does not exist, insert the value returned by the provided function and
17    /// return a mutable reference to it.
18    fn or_insert_with<F>(self, f: F) -> &'a mut Self::Value
19    where
20        F: FnOnce() -> Self::Value;
21}
22/// The [`OrInsert`] trait is a convenience trait that allows for the insertion of some value
23/// whenever the entry does not already exist within the container.
24pub trait OrInsert<K, V> {
25    fn or_insert(&mut self, key: K, value: V) -> V;
26}
27
28/*
29 ************* Implementations *************
30*/
31
32#[allow(unused_macros)]
33macro_rules! entry {
34    ($($prefix:ident)::* -> $call:ident($($arg:tt),*)) => {
35        $($prefix)::*::Entry::$call($($arg),*)
36    };
37}
38
39#[allow(unused_macros)]
40macro_rules! impl_entry {
41    ($($prefix:ident)::* $(where $($preds:tt)*)?) => {
42
43        impl<'a, K, V> Entry<'a> for $($prefix)::*::Entry<'a, K, V> $(where $($preds)*)? {
44            type Key = K;
45            type Value = V;
46
47            fn key(&self) -> &Self::Key {
48                entry!($($prefix)::* -> key(self))
49            }
50
51            fn or_insert(self, default: Self::Value) -> &'a mut Self::Value {
52                entry!($($prefix)::* -> or_insert(self, default))
53            }
54
55            fn or_insert_with<F>(self, f: F) -> &'a mut Self::Value
56            where
57                F: FnOnce() -> Self::Value,
58            {
59                entry!($($prefix)::* -> or_insert_with(self, f))
60            }
61        }
62
63    };
64}
65
66#[cfg(feature = "alloc")]
67impl_entry!(alloc::collections::btree_map where K: Ord);
68#[cfg(feature = "std")]
69impl_entry!(std::collections::hash_map where K: Eq + core::hash::Hash);