1use std::ops::Index;
7
8pub trait OrdMapValue<K>
12where
13 K: std::cmp::Eq + std::hash::Hash + Clone,
14{
15 fn key(&self) -> Option<K>;
17}
18
19#[derive(Clone, PartialEq)]
21pub struct OrdMap<K, V>
22where
23 V: OrdMapValue<K>,
24 K: std::cmp::Eq + std::hash::Hash + Clone,
25{
26 vec: Vec<V>,
28 map: std::collections::HashMap<K, usize>,
30}
31
32impl<K, V> Default for OrdMap<K, V>
33where
34 V: OrdMapValue<K>,
35 K: std::cmp::Eq + std::hash::Hash + Clone,
36{
37 fn default() -> Self {
38 Self {
39 vec: Default::default(),
40 map: Default::default(),
41 }
42 }
43}
44
45impl<K, V> std::fmt::Debug for OrdMap<K, V>
46where
47 V: OrdMapValue<K> + std::fmt::Debug,
48 K: std::cmp::Eq + std::hash::Hash + Clone,
49{
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 f.debug_struct("OrdMap").field("vec", &self.vec).finish()
52 }
53}
54
55impl<K, V> From<Vec<V>> for OrdMap<K, V>
56where
57 V: OrdMapValue<K>,
58 K: std::cmp::Eq + std::hash::Hash + Clone,
59{
60 fn from(vec: Vec<V>) -> Self {
61 let mut map = std::collections::HashMap::new();
62 for (i, item) in vec.iter().enumerate() {
64 if let Some(key) = item.key() {
65 map.insert(key, i);
66 }
67 }
68
69 Self { vec, map }
70 }
71}
72
73impl<K, V> OrdMap<K, V>
74where
75 V: OrdMapValue<K>,
76 K: std::cmp::Eq + std::hash::Hash + Clone,
77{
78 pub fn iter(&self) -> std::slice::Iter<'_, V> {
80 self.vec.iter()
81 }
82
83 pub fn len(&self) -> usize {
85 self.vec.len()
86 }
87
88 pub fn is_empty(&self) -> bool {
90 self.vec.is_empty()
91 }
92
93 pub fn try_push(&mut self, item: V) -> Result<(), K> {
95 if let Some(key) = item.key().clone() {
96 if self.map.contains_key(&key) {
97 return Err(key);
98 }
99 self.map.insert(key, self.vec.len());
100 }
101 self.vec.push(item);
102 Ok(())
103 }
104
105 pub fn get(&self, key: &K) -> Option<&V> {
107 self.map.get(key).map(|index| &self.vec[*index])
108 }
109
110 pub fn keys(&self) -> std::collections::hash_map::Keys<'_, K, usize> {
112 self.map.keys()
113 }
114
115 pub fn first(&self) -> Option<&V> {
117 self.vec.first()
118 }
119}
120
121impl<K, V> Index<usize> for OrdMap<K, V>
122where
123 V: OrdMapValue<K>,
124 K: std::cmp::Eq + std::hash::Hash + Clone,
125{
126 type Output = V;
127
128 fn index(&self, index: usize) -> &Self::Output {
129 &self.vec[index]
130 }
131}
132
133impl<K, V> Index<&K> for OrdMap<K, V>
134where
135 V: OrdMapValue<K>,
136 K: std::cmp::Eq + std::hash::Hash + Clone,
137{
138 type Output = V;
139
140 fn index(&self, key: &K) -> &Self::Output {
141 &self.vec[*self.map.get(key).expect("key not found")]
142 }
143}