fast_map/lib.rs
1/*!
2A small library and custom derive to create a map-like struct that uses match expressions to `get` and `insert` values.
3
4If you know your keys at compile-time, this library will likely be faster than `HashMap` for supported map operations.
5
6Provides the following operations on the wrapping struct (via `derive` macros):
7
8* `MyMap::get`, returns `Result<Option<&V>, Error>`
9* `MyMap::get_mut`, returns `Result<Option<&mut V>, Error>`
10* `MyMap::insert`, returns `Result<Option<V>, Error>`, where `V` is the old value if one exists
11* `MyMap::remove`, returns `Result<Option<V>, Error>`
12* `MyMap::values`, returns an iterator over `&V`s
13
14If you know that your operations cannot fail (e.g. if your key type is an `enum`, and you list all variants as keys),
15you can add `infallible = true` to your derive attributes, which will `unwrap` the result of your map operations.
16
17# Usage
18
19```rust,no_run
20
21fn main() {
22 pub enum A { A, B, C, D };
23
24 #[derive(Default, fast_map::FastMap)]
25 // We know this cannot fail, since we list all the `enum` variants, so we add `infallible = true`
26 #[fast_map(infallible = true, keys(A::A, A::B, A::C, A::D))]
27 struct Foo(fast_map::Map4<A, String>);
28
29 let mut foo = Foo::default();
30
31 foo.insert(A::B, "B".into());
32
33 assert_eq!(foo.get(A::B), Some(&"B".to_string()));
34
35 assert_eq!(foo.get(A::C), None);
36
37 foo.insert(A::C, "C".into());
38
39 assert_eq!(foo.values().collect::<Vec<_>>().len(), 2);
40}
41```
42
43# Changelog
44
45## 0.2.1
46
47* Add the non-erroring operations back as depending on macro attribute (`infallible = true`). Default is `false`.
48
49## 0.2.0
50
51* Removed `easy` and `strict` `MapLike` traits. It's better to handle unknown keys explicitly, even for `get`s.
52* Added `get_mut` operation to the wrapping struct
53
54*/
55
56pub use fast_map_derive::FastMap;
57
58/// Currently just `KeyNotFound`
59#[derive(Debug)]
60pub enum Error {
61 KeyNotFound,
62}
63
64impl std::fmt::Display for Error {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 match self {
67 Error::KeyNotFound => "Key not found".fmt(f),
68 }
69 }
70}
71
72impl std::error::Error for Error {}
73
74mod maps;
75
76pub use maps::*;
77
78/// Iterator over existing values
79pub struct Values<'fast_map, T>(std::vec::IntoIter<Option<&'fast_map T>>);
80
81impl<'fast_map, T> Values<'fast_map, T> {
82 #[doc(hidden)]
83 pub fn new(t: std::vec::IntoIter<Option<&'fast_map T>>) -> Self {
84 Values(t)
85 }
86}
87
88impl<'fast_map, T> Iterator for Values<'fast_map, T> {
89 type Item = &'fast_map T;
90 fn next(&mut self) -> Option<Self::Item> {
91 loop {
92 match self.0.next() {
93 Some(Some(ref inner)) => {
94 return Some(inner);
95 }
96 Some(None) => {
97 continue;
98 }
99 None => {
100 return None;
101 }
102 }
103 }
104 }
105}
106
107#[cfg(test)]
108mod tests {
109
110 use super::*;
111
112 #[test]
113 fn it_works() {
114 pub enum A {
115 A,
116 B,
117 C,
118 D,
119 };
120
121 #[derive(Default, FastMap)]
122 #[fast_map(infallible = true, crate_name = "crate", keys(A::A, A::B, A::C, A::D))]
123 struct Foo(crate::Map64<A, String>);
124
125 let mut foo = Foo::default();
126
127 foo.insert(A::B, "B".into());
128
129 assert_eq!(foo.get(A::B), Some(&"B".to_string()));
130
131 assert_eq!(foo.get(A::C), None);
132
133 foo.insert(A::C, "C".into());
134
135 assert_eq!(foo.values().collect::<Vec<_>>().len(), 2);
136 }
137
138 #[test]
139 fn it_works_2() {
140
141 #[derive(Default, FastMap)]
142 #[fast_map(crate_name = "crate", keys("x", "y", "z"))]
143 struct Foo<'a>(crate::Map3<str, &'a str>);
144
145 let mut foo = Foo::default();
146
147 let insert_x = String::from("x");
148
149 foo.insert(insert_x.as_str(), &insert_x).unwrap();
150
151 assert_eq!(foo.values().collect::<Vec<_>>().len(), 1);
152
153 let x = foo.remove("x").ok().flatten().unwrap();
154
155 assert_eq!(x, "x");
156
157 assert!(foo.values().collect::<Vec<_>>().is_empty());
158 }
159
160 #[test]
161 fn it_works_3() {
162
163 #[derive(Default, FastMap)]
164 #[fast_map(crate_name = "crate", keys(1, 2, 3))]
165 struct Foo<'a>(crate::Map3<usize, &'a str>);
166
167 let mut foo = Foo::default();
168
169 foo.insert(1, "1");
170 foo.insert(2, "2");
171 foo.insert(3, "3");
172 foo.insert(4, "4");
173
174 let _ = foo.remove(1);
175
176 assert_eq!(foo.values().map(|x| *x).collect::<Vec<_>>(), vec!["2", "3"]);
177 }
178}