maplike/lib.rs
1// SPDX-FileCopyrightText: 2025 maplike contributors
2//
3// SPDX-License-Identifier: MIT OR Apache-2.0
4
5#![doc(html_root_url = "https://docs.rs/maplike")]
6#![doc = include_str!("../README.md")]
7#![deny(missing_docs)]
8#![forbid(unsafe_code)]
9#![no_std]
10
11#[cfg(feature = "std")]
12extern crate std as _std;
13
14// No feature for `alloc` because it would be always enabled anyway.
15extern crate alloc as _alloc;
16
17/// A keyed collection without any operations defined.
18///
19/// A keyed collection is just a key-value map. We however use the name
20/// `KeyedCollection` instead of `Map` to distinguish maps from vectors and
21/// stable vectors, which also are keyed collections but with slightly different
22/// sets of operations.
23pub trait KeyedCollection {
24 /// Type of the keys in the keyed collection.
25 type Key;
26 /// Type of the values in the keyed collection.
27 type Value;
28}
29
30/// Returns a reference to the value corresponding to the key.
31pub trait Get<K>: KeyedCollection {
32 /// Returns a reference to the value corresponding to the key.
33 fn get(&self, key: &K) -> Option<&Self::Value>;
34}
35
36/// Insert a key-value pair into the collection.
37pub trait Insert<K>: KeyedCollection {
38 /// Insert a key-value pair into the collection.
39 fn insert(&mut self, key: K, value: Self::Value);
40}
41
42/// Remove an element under a key from the collection, returning the value at
43/// the key if the key was previously in the map.
44pub trait Remove<K>: KeyedCollection {
45 /// Remove a key from the collection, returning the value at the key if the
46 /// key was previously in the map.
47 fn remove(&mut self, key: &K) -> Option<Self::Value>;
48}
49
50/// Removing an element under a key using [`Remove::remove()`] does not
51/// invalidate any other key.
52///
53/// Plain vectors such as [`Vec`] cannot implement this trait because
54/// removing elements invalidates keys of other elements. Some contiguous data
55/// structures, such as [`stable_vec::StableVec`] and [`thunderdome::Arena`],
56/// bypass this limitation by placing a tombstone element in place of the
57/// removed element.
58pub trait StableRemove<K>: Remove<K> {}
59
60/// Insert a value into the collection without specifying a key, returning
61/// the key that was automatically generated.
62pub trait Push<K>: KeyedCollection {
63 /// Insert a value into the collection without specifying a key, returning
64 /// the key that was automatically generated.
65 fn push(&mut self, value: Self::Value) -> K;
66}
67
68/// Remove the last element of the collection, returning it.
69///
70/// If `Push` is also implemented, calling `Pop` should revert the previous
71/// pushes in their reversed order.
72pub trait Pop: KeyedCollection {
73 /// Remove the last element of the collection, returning it.
74 fn pop(&mut self) -> Option<Self::Value>;
75}
76
77/// Consume the collection and yield owned key-value pairs.
78pub trait IntoIter<K>: KeyedCollection {
79 /// Iterator that consumes the collection.
80 type IntoIter: Iterator<Item = (K, Self::Value)>;
81
82 /// Consume the collection and yield owned key-value pairs.
83 fn into_iter(self) -> Self::IntoIter;
84}
85
86/// A keyed collection with stable removes.
87pub trait Map<K>: Get<K> + Insert<K> + StableRemove<K> {}
88impl<K, T: Get<K> + Insert<K> + StableRemove<K>> Map<K> for T {}
89
90/// A keyed collection with pushes.
91pub trait Vec<K>: Get<K> + Insert<K> + Remove<K> + Push<K> {}
92impl<K, T: Get<K> + Insert<K> + Remove<K> + Push<K>> Vec<K> for T {}
93
94/// A keyed collection with stable removes and pushes.
95pub trait StableVec<K>: Vec<K> + StableRemove<K> {}
96impl<K, T: StableVec<K>> StableVec<K> for T {}
97
98#[cfg(feature = "std")]
99mod std;
100
101// No feature for alloc because it would be always enabled anyway.
102mod alloc;
103
104#[cfg(feature = "stable-vec")]
105mod stable_vec;
106
107#[cfg(feature = "thunderdome")]
108mod thunderdome;
109
110#[cfg(feature = "rstar")]
111mod rstar;