1use std::marker::PhantomData;
2
3pub struct IndexMap<K, V> {
4 _key: PhantomData<K>,
5 entries: Vec<V>,
6}
7
8impl<K, V> std::fmt::Debug for IndexMap<K, V>
9where
10 V: std::fmt::Debug,
11{
12 fn fmt(
13 &self,
14 f: &mut std::fmt::Formatter<'_>,
15 ) -> std::fmt::Result {
16 {
17 f.debug_struct("IndexMap").field("entries", &self.entries).finish()
18 }
19 }
20}
21
22impl<K, V> Clone for IndexMap<K, V>
23where
24 K: Clone,
25 V: Clone,
26{
27 fn clone(&self) -> Self {
28 IndexMap {
29 _key: self._key,
30 entries: self.entries.clone(),
31 }
32 }
33}
34
35impl<K, V> IndexMap<K, V> {
36 pub fn len(&self) -> usize {
37 self.entries.len()
38 }
39
40 pub fn is_empty(&self) -> bool {
41 self.entries.is_empty()
42 }
43}
44
45impl<K, V> Default for IndexMap<K, V>
46where
47 K: From<usize> + Into<usize>,
48{
49 fn default() -> Self {
50 Self {
51 entries: Default::default(),
52 _key: PhantomData,
53 }
54 }
55}
56
57impl<K, V> IndexMap<K, V>
58where
59 K: From<usize> + Into<usize>,
60{
61 pub fn iter(&self) -> impl Iterator<Item = (K, &V)> {
62 self.entries.iter().enumerate().map(|(k, v)| (K::from(k), v))
63 }
64
65 pub fn insert(
66 &mut self,
67 value: V,
68 ) -> K {
69 let key = self.entries.len();
70 self.entries.push(value);
71 key.into()
72 }
73
74 pub fn get(
75 &self,
76 k: K,
77 ) -> &V {
78 &self.entries[k.into()]
79 }
80
81 pub fn get_mut(
82 &mut self,
83 k: K,
84 ) -> &mut V {
85 self.entries
86 .get_mut(k.into())
87 .expect("IDs are handed out by insertion, so this should never fail")
88 }
89
90 #[allow(clippy::should_implement_trait)]
94 pub fn into_iter(self) -> impl Iterator<Item = (K, V)> {
95 self.entries.into_iter().enumerate().map(|(i, v)| (i.into(), v))
96 }
97}
98
99impl<K, V> IndexMap<K, V>
100where
101 K: From<usize>,
102 V: PartialEq,
103{
104 pub fn contains_value(
105 &self,
106 value: V,
107 ) -> Option<K> {
108 self.entries.iter().position(|v| *v == value).map(Into::into)
109 }
110}
111
112#[macro_export]
113macro_rules! idx_map_key {
114 ($(#[$attr:meta])*
115 $name:ident) => {
116 #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
117 $(#[$attr])*
118 pub struct $name(usize);
119
120 impl From<usize> for $name {
121 fn from(value: usize) -> Self {
122 Self(value)
123 }
124 }
125
126 impl From<$name> for usize {
127 fn from(value: $name) -> usize {
128 value.0
129 }
130 }
131
132 impl std::fmt::Display for $name {
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 write!(f, "{}{}", stringify!($name).to_lowercase(), self.0)
135 }
136 }
137 };
138}