1use indexmap::map::Iter as MapIter;
2use indexmap::map::Keys as MapKeys;
3use indexmap::map::Values as MapValues;
4use indexmap::IndexMap as Map;
5use std::borrow::Borrow;
6use std::fmt;
7use std::hash::Hash;
8
9use crate::ImplicitClone;
10
11use super::IString;
12use super::Rc;
13
14#[cfg_attr(docsrs, doc(cfg(feature = "map")))]
23#[derive(PartialEq, Eq)]
24pub enum IMap<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> {
25 Static(&'static [(K, V)]),
27 Rc(Rc<Map<K, V>>),
29}
30
31impl<
33 K: fmt::Debug + Eq + Hash + ImplicitClone + 'static,
34 V: fmt::Debug + PartialEq + ImplicitClone + 'static,
35 > fmt::Debug for IMap<K, V>
36{
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 match self {
39 Self::Static(a) => a.fmt(f),
40 Self::Rc(a) => a.fmt(f),
41 }
42 }
43}
44
45impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Clone
46 for IMap<K, V>
47{
48 fn clone(&self) -> Self {
49 match self {
50 Self::Static(a) => Self::Static(a),
51 Self::Rc(a) => Self::Rc(a.clone()),
52 }
53 }
54}
55
56impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Default
57 for IMap<K, V>
58{
59 fn default() -> Self {
60 Self::Static(&[])
61 }
62}
63
64impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static>
65 FromIterator<(K, V)> for IMap<K, V>
66{
67 fn from_iter<I: IntoIterator<Item = (K, V)>>(it: I) -> Self {
68 let vec = it.into_iter().collect::<Map<K, V>>();
69 Self::Rc(Rc::from(vec))
70 }
71}
72
73impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> ImplicitClone
74 for IMap<K, V>
75{
76}
77
78impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static>
79 From<&'static [(K, V)]> for IMap<K, V>
80{
81 fn from(a: &'static [(K, V)]) -> IMap<K, V> {
82 IMap::Static(a)
83 }
84}
85
86impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> From<Map<K, V>>
87 for IMap<K, V>
88{
89 fn from(a: Map<K, V>) -> IMap<K, V> {
90 IMap::Rc(Rc::new(a))
91 }
92}
93
94impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static>
95 From<Rc<Map<K, V>>> for IMap<K, V>
96{
97 fn from(a: Rc<Map<K, V>>) -> IMap<K, V> {
98 IMap::Rc(a)
99 }
100}
101
102impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static>
103 From<&IMap<K, V>> for IMap<K, V>
104{
105 fn from(a: &IMap<K, V>) -> IMap<K, V> {
106 a.clone()
107 }
108}
109
110impl<K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> IMap<K, V> {
111 #[inline]
113 pub fn iter(&self) -> IMapIter<K, V> {
114 match self {
115 Self::Static(a) => IMapIter::Slice(a.iter()),
116 Self::Rc(a) => IMapIter::Map(a.iter()),
117 }
118 }
119
120 #[inline]
122 pub fn keys(&self) -> IMapKeys<K, V> {
123 match self {
124 Self::Static(a) => IMapKeys::Slice(a.iter()),
125 Self::Rc(a) => IMapKeys::Map(a.keys()),
126 }
127 }
128
129 #[inline]
131 pub fn values(&self) -> IMapValues<K, V> {
132 match self {
133 Self::Static(a) => IMapValues::Slice(a.iter()),
134 Self::Rc(a) => IMapValues::Map(a.values()),
135 }
136 }
137
138 #[inline]
142 pub fn len(&self) -> usize {
143 match self {
144 Self::Static(a) => a.len(),
145 Self::Rc(a) => a.len(),
146 }
147 }
148
149 #[inline]
153 pub fn is_empty(&self) -> bool {
154 match self {
155 Self::Static(a) => a.is_empty(),
156 Self::Rc(a) => a.is_empty(),
157 }
158 }
159
160 #[inline]
165 pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<V>
166 where
167 K: Borrow<Q>,
168 Q: Hash + Eq,
169 {
170 match self {
171 Self::Static(a) => a
172 .iter()
173 .find_map(|(k, v)| (k.borrow() == key).then(|| v))
174 .cloned(),
175 Self::Rc(a) => a.get(key).cloned(),
176 }
177 }
178
179 #[inline]
184 pub fn get_key_value<Q: ?Sized>(&self, key: &Q) -> Option<(K, V)>
185 where
186 K: Borrow<Q>,
187 Q: Hash + Eq,
188 {
189 match self {
190 Self::Static(a) => a.iter().find(|(k, _)| k.borrow() == key).cloned(),
191 Self::Rc(a) => a.get_key_value(key).map(|(k, v)| (k.clone(), v.clone())),
192 }
193 }
194
195 #[inline]
197 pub fn get_full<Q: ?Sized>(&self, key: &Q) -> Option<(usize, K, V)>
198 where
199 K: Borrow<Q>,
200 Q: Hash + Eq,
201 {
202 match self {
203 Self::Static(a) => a
204 .iter()
205 .enumerate()
206 .find_map(|(i, (k, v))| (k.borrow() == key).then(|| (i, k.clone(), v.clone()))),
207 Self::Rc(a) => a.get_full(key).map(|(i, k, v)| (i, k.clone(), v.clone())),
208 }
209 }
210
211 #[inline]
217 pub fn get_index(&self, index: usize) -> Option<(K, V)> {
218 match self {
219 Self::Static(a) => a.get(index).cloned(),
220 Self::Rc(a) => a.get_index(index).map(|(k, v)| (k.clone(), v.clone())),
221 }
222 }
223
224 #[inline]
228 pub fn get_index_of<Q: ?Sized>(&self, key: &Q) -> Option<usize>
229 where
230 K: Borrow<Q>,
231 Q: Hash + Eq,
232 {
233 match self {
234 Self::Static(a) => a
235 .iter()
236 .enumerate()
237 .find_map(|(i, (k, _))| (k.borrow() == key).then(|| i)),
238 Self::Rc(a) => a.get_index_of(key),
239 }
240 }
241
242 #[inline]
246 pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
247 where
248 K: Borrow<Q>,
249 Q: Hash + Eq,
250 {
251 match self {
252 Self::Static(a) => a.iter().any(|(k, _)| k.borrow() == key),
253 Self::Rc(a) => a.contains_key(key),
254 }
255 }
256
257 #[inline]
261 pub fn last(&self) -> Option<(K, V)> {
262 match self {
263 Self::Static(a) => a.last().cloned(),
264 Self::Rc(a) => a.last().map(|(k, v)| (k.clone(), v.clone())),
265 }
266 }
267}
268
269impl<V: PartialEq + ImplicitClone + 'static> IMap<IString, V> {
270 #[doc(hidden)]
271 #[inline]
272 pub fn get_static_str(&self, key: &'static str) -> Option<V> {
273 let key = IString::from(key);
274 match self {
275 Self::Static(a) => a.iter().find_map(|(k, v)| (*k == key).then(|| v)).cloned(),
276 Self::Rc(a) => a.get(&key).cloned(),
277 }
278 }
279}
280
281impl<V: PartialEq + ImplicitClone + 'static> IMap<&'static str, V> {
282 #[doc(hidden)]
283 #[inline]
284 pub fn get_static_str(&self, key: &'static str) -> Option<V> {
285 match self {
286 Self::Static(a) => a.iter().find_map(|(k, v)| (*k == key).then(|| v)).cloned(),
287 Self::Rc(a) => a.get(key).cloned(),
288 }
289 }
290}
291
292#[allow(missing_docs, missing_debug_implementations)]
293pub enum IMapIter<'a, K, V> {
294 Slice(std::slice::Iter<'a, (K, V)>),
295 Map(MapIter<'a, K, V>),
296}
297
298impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator
299 for IMapIter<'a, K, V>
300{
301 type Item = (K, V);
302
303 fn next(&mut self) -> Option<Self::Item> {
304 match self {
305 Self::Slice(it) => it.next().map(|(k, v)| (k.clone(), v.clone())),
306 Self::Map(it) => it.next().map(|(k, v)| (k.clone(), v.clone())),
307 }
308 }
309}
310
311#[allow(missing_docs, missing_debug_implementations)]
312pub enum IMapKeys<'a, K, V> {
313 Slice(std::slice::Iter<'a, (K, V)>),
314 Map(MapKeys<'a, K, V>),
315}
316
317impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator
318 for IMapKeys<'a, K, V>
319{
320 type Item = K;
321
322 fn next(&mut self) -> Option<Self::Item> {
323 match self {
324 Self::Slice(it) => it.next().map(|(k, _)| k.clone()),
325 Self::Map(it) => it.next().cloned(),
326 }
327 }
328}
329
330#[allow(missing_docs, missing_debug_implementations)]
331pub enum IMapValues<'a, K, V> {
332 Slice(std::slice::Iter<'a, (K, V)>),
333 Map(MapValues<'a, K, V>),
334}
335
336impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator
337 for IMapValues<'a, K, V>
338{
339 type Item = V;
340
341 fn next(&mut self) -> Option<Self::Item> {
342 match self {
343 Self::Slice(it) => it.next().map(|(_, v)| v.clone()),
344 Self::Map(it) => it.next().cloned(),
345 }
346 }
347}
348
349#[cfg(feature = "serde")]
350impl<K, V> serde::Serialize for IMap<K, V>
351where
352 K: Eq + Hash + ImplicitClone + 'static + serde::Serialize,
353 V: PartialEq + ImplicitClone + 'static + serde::Serialize,
354{
355 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
356 use serde::ser::SerializeMap;
357 let mut seq = serializer.serialize_map(Some(self.len()))?;
358 match self {
359 Self::Static(a) => {
360 for (k, v) in a.iter() {
361 seq.serialize_entry(k, v)?;
362 }
363 }
364 Self::Rc(a) => {
365 for (k, v) in a.iter() {
366 seq.serialize_entry(k, v)?;
367 }
368 }
369 }
370 seq.end()
371 }
372}
373
374#[cfg(feature = "serde")]
375impl<'de, K, V> serde::Deserialize<'de> for IMap<K, V>
376where
377 K: Eq + Hash + ImplicitClone + 'static + serde::Deserialize<'de>,
378 V: PartialEq + ImplicitClone + 'static + serde::Deserialize<'de>,
379{
380 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
381 <Map<K, V> as serde::Deserialize>::deserialize(deserializer).map(IMap::<K, V>::from)
382 }
383}
384
385#[cfg(test)]
386mod test_map {
387 use super::*;
388
389 #[test]
390 fn map_in_map() {
391 let map_1 = [
392 (IString::from("foo1"), 1),
393 (IString::from("bar1"), 2),
394 (IString::from("baz1"), 3),
395 ]
396 .into_iter()
397 .collect::<IMap<IString, u32>>();
398 let map_2 = [
399 (IString::from("foo2"), 4),
400 (IString::from("bar2"), 5),
401 (IString::from("baz2"), 6),
402 ]
403 .into_iter()
404 .collect::<IMap<IString, u32>>();
405 let map_of_map = [("map_1", map_1), ("map_2", map_2)]
406 .into_iter()
407 .collect::<IMap<&'static str, IMap<IString, u32>>>();
408 let flattened_vec = map_of_map
409 .iter()
410 .flat_map(|(_key, map)| map.iter().collect::<Vec<(_, _)>>())
411 .collect::<Vec<(_, _)>>();
412 assert_eq!(
414 flattened_vec,
415 [
416 (IString::from("foo1"), 1),
417 (IString::from("bar1"), 2),
418 (IString::from("baz1"), 3),
419 (IString::from("foo2"), 4),
420 (IString::from("bar2"), 5),
421 (IString::from("baz2"), 6),
422 ]
423 );
424 }
425
426 #[test]
427 fn static_map() {
428 const _MAP: IMap<&str, u32> = IMap::Static(&[("foo", 1)]);
429 }
430
431 #[test]
432 fn floats_in_map() {
433 const _MAP_F32: IMap<u32, f32> = IMap::Static(&[]);
434 const _MAP_F64: IMap<u32, f64> = IMap::Static(&[]);
435 }
436
437 #[test]
438 fn from() {
439 let x: IMap<u32, u32> = IMap::Static(&[]);
440 let _out = IMap::from(&x);
441 }
442}