1#![allow(dead_code)]
2
3use std::borrow::Borrow;
4
5pub struct AssocList<K, V>(Vec<(K, V)>);
6pub enum Entry<'a, K, V> {
7 Vacant(VacantEntry<'a, K, V>),
8 Occupied(OccupiedEntry<'a, K, V>),
9}
10pub struct VacantEntry<'a, K, V> {
11 key: K,
12 map: &'a mut AssocList<K, V>,
13}
14pub struct OccupiedEntry<'a, K, V> {
15 key: K,
16 map: &'a mut AssocList<K, V>,
17}
18
19impl<K: Eq, V> AssocList<K, V> {
20 pub fn new() -> Self { Self(vec![]) }
21
22 pub fn is_empty(&self) -> bool { self.0.is_empty() }
23 pub fn len(&self) -> usize { self.0.len() }
24
25 pub fn get<Q>(&self, key: Q) -> Option<&V>
26 where
27 Q: Borrow<K>,
28 K: PartialEq<Q>,
29 {
30 self.0.iter().find(|(k, _)| k == &key).map(|(_, v)| v)
31 }
32
33 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
34 if let Some((_, v)) = self.0.iter_mut().find(|(k, _)| k == &key) {
35 Some(std::mem::replace(v, value))
36 } else {
37 self.0.push((key, value));
38 None
39 }
40 }
41
42 pub fn remove<Q>(&mut self, key: Q) -> Option<V>
43 where
44 Q: Borrow<K>,
45 K: PartialEq<Q>,
46 {
47 (0..self.0.len())
48 .find(|&i| self.0[i].0 == key)
49 .map(|i| self.0.remove(i).1)
50 }
51
52 pub fn entry(&mut self, key: K) -> Entry<K, V> {
53 if self.0.iter().any(|(k, _)| k == &key) {
54 Entry::occupied(key, self)
55 } else {
56 Entry::vacant(key, self)
57 }
58 }
59}
60
61impl<K: Eq, V> Default for AssocList<K, V> {
62 fn default() -> Self { Self::new() }
63}
64
65impl<'a, K: Eq, V> Entry<'a, K, V> {
66 pub(crate) fn vacant(key: K, map: &'a mut AssocList<K, V>) -> Self {
67 Self::Vacant(VacantEntry { key, map })
68 }
69 pub(crate) fn occupied(key: K, map: &'a mut AssocList<K, V>) -> Self {
70 Self::Occupied(OccupiedEntry { key, map })
71 }
72
73 pub fn and_modify<F: FnOnce(&mut V)>(self, f: F) -> Entry<'a, K, V> {
74 match self {
75 Self::Occupied(mut entry) => {
76 f(entry.get_mut());
77 Self::Occupied(entry)
78 }
79 Self::Vacant(entry) => Self::Vacant(entry),
80 }
81 }
82
83 pub fn key(&self) -> &K {
84 match *self {
85 Self::Occupied(ref entry) => entry.key(),
86 Self::Vacant(ref entry) => entry.key(),
87 }
88 }
89 pub fn or_default(self) -> &'a mut V
90 where
91 V: Default,
92 {
93 match self {
94 Self::Occupied(entry) => entry.into_mut(),
95 Self::Vacant(entry) => entry.insert(Default::default()),
96 }
97 }
98 pub fn or_insert(self, default: V) -> &'a mut V {
99 match self {
100 Self::Occupied(entry) => entry.into_mut(),
101 Self::Vacant(entry) => entry.insert(default),
102 }
103 }
104 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
105 match self {
106 Self::Occupied(entry) => entry.into_mut(),
107 Self::Vacant(entry) => entry.insert(default()),
108 }
109 }
110 pub fn or_insert_with_key<F: FnOnce(&K) -> V>(
111 self,
112 default: F,
113 ) -> &'a mut V {
114 match self {
115 Self::Occupied(entry) => entry.into_mut(),
116 Self::Vacant(entry) => {
117 let value = default(entry.key());
118 entry.insert(value)
119 }
120 }
121 }
122}
123
124impl<'a, K: Eq, V> VacantEntry<'a, K, V> {
125 pub fn into_key(self) -> K { self.key }
126 pub fn key(&self) -> &K { &self.key }
127 pub fn insert(self, value: V) -> &'a mut V {
128 let Self { key, map } = self;
129 map.0.push((key, value));
130 &mut map.0.last_mut().unwrap().1
131 }
132}
133
134impl<'a, K: Eq, V> OccupiedEntry<'a, K, V> {
135 pub fn insert(&mut self, value: V) -> V {
136 std::mem::replace(self.get_mut(), value)
137 }
138 pub fn get(&self) -> &V {
139 let Self { key, map } = self;
140 map.0.iter().find(|(k, _)| k == key).map(|(_, v)| v).unwrap()
141 }
142 pub fn get_mut(&mut self) -> &mut V {
143 let Self { key, map } = self;
144 map.0.iter_mut().find(|(k, _)| k == key).map(|(_, v)| v).unwrap()
145 }
146 pub fn into_mut(self) -> &'a mut V {
147 let Self { key, map } = self;
148 map.0.iter_mut().find(|(k, _)| k == &key).map(|(_, v)| v).unwrap()
149 }
150 pub fn key(&self) -> &K { &self.key }
151 pub fn remove(self) -> V { self.remove_entry().1 }
152 pub fn remove_entry(self) -> (K, V) {
153 let Self { key, map } = self;
154 let i = (0..map.len()).find(|&i| key == map.0[i].0).unwrap();
155 map.0.remove(i)
156 }
157}
158
159#[test]
160fn sanity_check() {
161 let mut alist = AssocList::new();
162
163 assert_eq!(alist.entry(0).key(), &0);
164
165 alist.entry(0).or_insert("zero");
166 assert_eq!(alist.get(0).unwrap(), &"zero");
167 assert_eq!(alist.len(), 1);
168
169 alist.entry(0).or_insert_with(|| "xxx");
170 assert_eq!(alist.get(0).unwrap(), &"zero");
171 assert_eq!(alist.len(), 1);
172
173 alist.entry(2).or_insert_with_key(|_| "two");
174 assert!(alist.get(1).is_none());
175 assert_eq!(alist.get(2).unwrap(), &"two");
176 assert_eq!(alist.len(), 2);
177
178 alist.entry(2).and_modify(|v| *v = "second");
179 assert_eq!(alist.len(), 2);
180
181 if let Entry::Occupied(o) = alist.entry(2) {
182 assert_eq!(o.get(), &"second");
183 assert_eq!(o.remove(), "second");
184 assert_eq!(alist.len(), 1);
185 }
186
187 alist.entry(1).or_default();
188 assert_eq!(alist.len(), 2);
189 assert!(alist.get(1).unwrap().is_empty());
190 if let Entry::Occupied(mut o) = alist.entry(1) {
191 o.insert("first");
192 assert_eq!(o.get(), &"first");
193 }
194}