fixed_map/key.rs
1//! Module for the trait to define a `Key`.
2
3#[cfg(feature = "hashbrown")]
4use crate::map::storage::HashbrownMapStorage;
5use crate::map::storage::{BooleanMapStorage, MapStorage, OptionMapStorage, SingletonMapStorage};
6#[cfg(feature = "hashbrown")]
7use crate::set::storage::HashbrownSetStorage;
8use crate::set::storage::{BooleanSetStorage, OptionSetStorage, SetStorage, SingletonSetStorage};
9
10/// The trait for a key that can be used to store values in a
11/// [`Map`][crate::Set] or [`Set`][crate::Set].
12///
13/// This is implemented automatically from enums through the
14/// [`Key`][key-derive]. The following is a *simple* key which has no nested
15/// keys:
16///
17/// ```
18/// use fixed_map::Key;
19///
20/// #[derive(Clone, Copy, Key)]
21/// enum MyKey {
22/// First,
23/// Second,
24/// }
25/// ```
26///
27/// *Composite keys* are when keys structurally includes other keys. They have
28/// slightly worse performance than simple keys because they can't be simply
29/// arranged as arrays internally. `bool` below here implements [`Key`] and
30/// using it in one key constructs a composite key. It's a simple form of key
31/// since it can only inhabit two values - `true` or `false`. `Option<K>` can
32/// also be used as a composite key:
33///
34/// ```
35/// use fixed_map::Key;
36///
37/// #[derive(Clone, Copy, Key)]
38/// enum MyKey {
39/// First(bool),
40/// Second(Option<bool>),
41/// }
42/// ```
43///
44/// Some composite keys require dynamic storage since they can inhabit a large
45/// number of values, and preferrably should be avoided in favor of using a
46/// `HashMap` directly. But if you absolutely have to you can enable the `map`
47/// feature:
48///
49/// ```
50/// use fixed_map::Key;
51///
52/// #[derive(Clone, Copy, Key)]
53/// enum MyKey {
54/// # #[cfg(feature = "hashbrown")]
55/// First(u32),
56/// Second,
57/// }
58/// ```
59///
60/// ## Ordering
61///
62/// Keys provide their own ordering semantics instead of relying on the
63/// [`PartialOrd`] and [`Ord`] traits.
64///
65/// Therefore keys when stored in a collection such as [`Map`] and [`Set`] are
66/// always ordered in *declaration order*. This allows those containers
67/// themselves to be ordered if the underlying key supports, it similarly to how
68/// [`BTreeMap`] and [`BTreeSet`] works.
69///
70/// ```
71/// use fixed_map::{Key, Set};
72///
73/// #[derive(Clone, Copy, Key)]
74/// enum MyKey {
75/// First,
76/// Second,
77/// Third,
78/// }
79///
80/// let mut a = Set::new();
81/// a.insert(MyKey::First);
82///
83/// let mut b = Set::new();
84/// b.insert(MyKey::Third);
85///
86/// let mut c = Set::new();
87/// c.insert(MyKey::First);
88/// c.insert(MyKey::Third);
89///
90/// assert!(a < b);
91/// assert!(c < b);
92/// assert!(a < c);
93/// ```
94///
95/// The same example with [`BTreeSet`]:
96///
97/// ```
98/// use std::collections::BTreeSet;
99///
100/// #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
101/// enum MyKey {
102/// First,
103/// Second,
104/// Third,
105/// }
106///
107/// let mut a = BTreeSet::new();
108/// a.insert(MyKey::First);
109///
110/// let mut b = BTreeSet::new();
111/// b.insert(MyKey::Third);
112///
113/// let mut c = BTreeSet::new();
114/// c.insert(MyKey::First);
115/// c.insert(MyKey::Third);
116///
117/// assert!(a < b);
118/// assert!(c < b);
119/// assert!(a < c);
120/// ```
121///
122/// [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
123/// [`BTreeSet`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html
124/// [`Map`]: crate::Map
125/// [`Set`]: crate::Set
126/// [key-derive]: derive@crate::Key
127pub trait Key: Copy {
128 /// The [`Map`][crate::Map] storage implementation to use for the key
129 /// implementing this trait.
130 type MapStorage<V>: MapStorage<Self, V>;
131
132 /// The [`Set`][crate::Set] storage implementation to use for the key
133 /// implementing this trait.
134 type SetStorage: SetStorage<Self>;
135}
136
137impl Key for bool {
138 type MapStorage<V> = BooleanMapStorage<V>;
139 type SetStorage = BooleanSetStorage;
140}
141
142impl<K> Key for Option<K>
143where
144 K: Key,
145{
146 type MapStorage<V> = OptionMapStorage<K, V>;
147 type SetStorage = OptionSetStorage<K>;
148}
149
150macro_rules! map_key {
151 ($ty:ty) => {
152 #[cfg(feature = "hashbrown")]
153 impl Key for $ty {
154 type MapStorage<V> = HashbrownMapStorage<$ty, V>;
155 type SetStorage = HashbrownSetStorage<$ty>;
156 }
157 };
158}
159
160macro_rules! singleton_key {
161 ($ty:ty) => {
162 impl Key for $ty {
163 type MapStorage<V> = SingletonMapStorage<V>;
164 type SetStorage = SingletonSetStorage;
165 }
166 };
167}
168
169map_key!(char);
170map_key!(u8);
171map_key!(u32);
172map_key!(u64);
173map_key!(u128);
174map_key!(usize);
175map_key!(i8);
176map_key!(i32);
177map_key!(i64);
178map_key!(i128);
179map_key!(isize);
180map_key!(&'static str);
181map_key!(&'static [u8]);
182singleton_key!(());