bidir_map/lib.rs
1//! Bidirectional maps for Rust.
2//!
3//! # Examples
4//!
5//! ```
6//! use bidir_map::{BidirMap, ByFirst, BySecond};
7//! use std::default::Default;
8//!
9//! let mut map = BidirMap::new();
10//! assert_eq!(map, Default::default());
11//!
12//! map.insert(1, "a");
13//!
14//! assert_eq!(map.get_by_first(&1), Some(&"a"));
15//! assert_eq!(map.get_by_first(&2), None);
16//! assert_eq!(map.get_by_second(&"a"), Some(&1));
17//! assert_eq!(map.get_by_second(&"b"), None);
18//!
19//! assert_eq!(map[ByFirst(&1)], "a");
20//! assert_eq!(map[BySecond(&"a")], 1);
21//! // These would panic:
22//! // map[ByFirst(&2)];
23//! // map[BySecond(&"b")];
24//! ```
25
26
27use std::borrow::Borrow;
28use std::slice;
29use std::iter::{Extend, FromIterator};
30use std::ops::Index;
31use std::vec;
32
33
34/// Create a `BidirMap` from a set of K/V-K/V pairs.
35///
36/// # Examples
37///
38/// ```
39/// #[macro_use]
40/// extern crate bidir_map;
41/// # fn main() {
42/// let map = bidir_map!(
43/// "a" => 1,
44/// "b" => 2,
45/// );
46///
47/// assert_eq!(map.get_by_first(&"a"), Some(&1));
48/// assert_eq!(map.get_by_second(&2), Some(&"b"));
49/// assert_eq!(map.get_by_first(&"c"), None);
50/// # let mut best_map = bidir_map::BidirMap::new();
51/// # best_map.insert("a", 1);
52/// # best_map.insert("b", 2);
53/// # assert_eq!(map, best_map);
54/// # }
55/// ```
56#[macro_export]
57macro_rules! bidir_map {
58 (@single $($x:tt)*) => (());
59 (@count $($rest:expr),*) => (<[()]>::len(&[$(bidir_map!(@single $rest)),*]));
60
61 // Ideally the separator would be <=> instead of => but it's parsed as <= > and therefore illegal
62 ($($key:expr => $value:expr,)+) => { bidir_map!($($key => $value),+) };
63 ($($key:expr => $value:expr),*) => {{
64 let cap = bidir_map!(@count $($key),*);
65 let mut map = ::bidir_map::BidirMap::with_capacity(cap);
66 $(map.insert($key, $value);)*
67 map
68 }};
69}
70
71
72/// A bidirectional map.
73///
74/// Bidirectional maps allow for mapping from and to both types.
75///
76/// The interface is based on that of `BTreeMap`, except, that for all functions, where one would supply a key, there are two functions,
77/// each treating one of the types as keys (`get()` -> `get_by_{first,second}()`).
78///
79/// Performance: `O(n)`, mostly.
80#[derive(Default, Clone, Debug, Hash, PartialEq, Eq)]
81pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
82 cont: Vec<(Kv1, Kv2)>,
83}
84
85impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
86 /// Create a new empty instance of `BidirMap`
87 pub fn new() -> Self {
88 BidirMap{
89 cont: Vec::new(),
90 }
91 }
92
93 /// Create a new empty instance of `BidirMap` with the specified capacity.
94 ///
95 /// It will be able to hold at least `capacity` elements without reallocating.
96 pub fn with_capacity(capacity: usize) -> Self {
97 BidirMap{
98 cont: Vec::with_capacity(capacity),
99 }
100 }
101
102 /// Clears the map, removing all entries.
103 ///
104 /// # Examples
105 ///
106 /// ```
107 /// use bidir_map::BidirMap;
108 ///
109 /// let mut a = BidirMap::new();
110 /// a.insert(1, "a");
111 /// a.clear();
112 /// assert!(a.is_empty());
113 /// ```
114 pub fn clear(&mut self) {
115 self.cont.clear()
116 }
117
118 /// Inserts a K/V-K/V pair into the map.
119 ///
120 /// If the map did not have this K/V-K/V pair present, `None` is returned.
121 ///
122 /// If the map did have this K/V-K/V pair present, it's updated and the old K/V-K/V pair is returned.
123 pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) -> Option<(Kv1, Kv2)> {
124 let retval =
125 if self.contains_first_key(&kv1) {
126 self.remove_by_first(&kv1)
127 } else if self.contains_second_key(&kv2) {
128 self.remove_by_second(&kv2)
129 } else {
130 None
131 };
132
133 self.cont.push((kv1, kv2));
134
135 retval
136 }
137
138 /// Gets an iterator over the entries of the map.
139 ///
140 /// # Examples
141 ///
142 /// ```
143 /// use bidir_map::BidirMap;
144 ///
145 /// let mut map = BidirMap::new();
146 /// map.insert(1, "a");
147 /// map.insert(2, "b");
148 /// map.insert(3, "c");
149 ///
150 /// for kv in map.iter() {
151 /// println!("{}: {}", kv.0, kv.1);
152 /// }
153 ///
154 /// let first = map.iter().next().unwrap();
155 /// assert_eq!(first, (&1, &"a"));
156 /// ```
157 pub fn iter(&self) -> Iter<Kv1, Kv2> {
158 Iter{
159 iter: self.cont.iter(),
160 }
161 }
162
163 /// Gets a mutable iterator over the entries of the map.
164 ///
165 /// # Examples
166 ///
167 /// ```
168 /// # #[macro_use]
169 /// # extern crate bidir_map;
170 /// # fn main() {
171 /// use bidir_map::BidirMap;
172 ///
173 /// let mut map = BidirMap::new();
174 /// map.insert("a", 1);
175 /// map.insert("b", 2);
176 /// map.insert("c", 3);
177 ///
178 /// // add 10 to the value if the key isn't "a"
179 /// for kv in map.iter_mut() {
180 /// if *kv.0 != "a" {
181 /// *kv.1 += 10;
182 /// }
183 /// }
184 /// # assert_eq!(map, bidir_map!["a" => 1, "b" => 12, "c" => 13]);
185 /// # }
186 /// ```
187 pub fn iter_mut(&mut self) -> IterMut<Kv1, Kv2> {
188 IterMut{
189 iter: self.cont.iter_mut(),
190 }
191 }
192
193 /// Gets an iterator over the first K/V of the map.
194 ///
195 /// # Examples
196 ///
197 /// ```
198 /// use bidir_map::BidirMap;
199 ///
200 /// let mut a = BidirMap::new();
201 /// a.insert(1, "a");
202 /// a.insert(2, "b");
203 ///
204 /// let keys: Vec<_> = a.first_col().cloned().collect();
205 /// assert_eq!(keys, [1, 2]);
206 /// ```
207 pub fn first_col(&self) -> FirstColumn<Kv1, Kv2> {
208 FirstColumn{
209 iter: self.cont.iter(),
210 }
211 }
212
213 /// Gets an iterator over the second K/V of the map.
214 ///
215 /// # Examples
216 ///
217 /// ```
218 /// use bidir_map::BidirMap;
219 ///
220 /// let mut a = BidirMap::new();
221 /// a.insert(1, "a");
222 /// a.insert(2, "b");
223 ///
224 /// let keys: Vec<_> = a.second_col().cloned().collect();
225 /// assert_eq!(keys, ["a", "b"]);
226 /// ```
227 pub fn second_col(&self) -> SecondColumn<Kv1, Kv2> {
228 SecondColumn{
229 iter: self.cont.iter(),
230 }
231 }
232
233 /// Returns the number of elements in the map.
234 ///
235 /// # Examples
236 ///
237 /// ```
238 /// use bidir_map::BidirMap;
239 ///
240 /// let mut a = BidirMap::new();
241 /// assert_eq!(a.len(), 0);
242 /// a.insert(1, "a");
243 /// assert_eq!(a.len(), 1);
244 /// ```
245 pub fn len(&self) -> usize {
246 self.cont.len()
247 }
248
249 /// Returns true if the map contains no elements.
250 ///
251 /// # Examples
252 ///
253 /// ```
254 /// use bidir_map::BidirMap;
255 ///
256 /// let mut a = BidirMap::new();
257 /// assert!(a.is_empty());
258 /// a.insert(1, "a");
259 /// assert!(!a.is_empty());
260 /// ```
261 pub fn is_empty(&self) -> bool {
262 self.cont.is_empty()
263 }
264
265
266 /// Returns a reference to the second K/V corresponding to the first K/V.
267 ///
268 /// # Examples
269 ///
270 /// ```
271 /// use bidir_map::BidirMap;
272 ///
273 /// let mut map = BidirMap::new();
274 /// map.insert(1, "a");
275 /// assert_eq!(map.get_by_first(&1), Some(&"a"));
276 /// assert_eq!(map.get_by_first(&2), None);
277 /// ```
278 pub fn get_by_first<Q: ?Sized>(&self, key: &Q) -> Option<&Kv2>
279 where Kv1: Borrow<Q>,
280 Q : PartialEq<Kv1>,
281 {
282 self.cont.iter().find(|&kvs| *key == kvs.0).map(|ref kvs| &kvs.1)
283 }
284
285 /// Returns a reference to the first K/V corresponding to the second K/V.
286 ///
287 /// # Examples
288 ///
289 /// ```
290 /// use bidir_map::BidirMap;
291 ///
292 /// let mut map = BidirMap::new();
293 /// map.insert(1, "a");
294 /// assert_eq!(map.get_by_second(&"a"), Some(&1));
295 /// assert_eq!(map.get_by_second(&"b"), None);
296 /// ```
297 pub fn get_by_second<Q: ?Sized>(&self, key: &Q) -> Option<&Kv1>
298 where Kv2: Borrow<Q>,
299 Q : PartialEq<Kv2>,
300 {
301 self.cont.iter().find(|&kvs| *key == kvs.1).map(|ref kvs| &kvs.0)
302 }
303
304 /// Check if the map contains the first K/V
305 ///
306 /// # Examples
307 ///
308 /// ```
309 /// use bidir_map::BidirMap;
310 ///
311 /// let mut map = BidirMap::new();
312 /// map.insert(1, "a");
313 /// assert_eq!(map.contains_first_key(&1), true);
314 /// assert_eq!(map.contains_first_key(&2), false);
315 /// ```
316 pub fn contains_first_key<Q: ?Sized>(&self, key: &Q) -> bool
317 where Kv1: Borrow<Q>,
318 Q : PartialEq<Kv1>,
319 {
320 self.cont.iter().any(|ref kvs| *key == kvs.0)
321 }
322
323 /// Check if the map contains the second K/V
324 ///
325 /// # Examples
326 ///
327 /// ```
328 /// use bidir_map::BidirMap;
329 ///
330 /// let mut map = BidirMap::new();
331 /// map.insert(1, "a");
332 /// assert_eq!(map.contains_second_key(&"a"), true);
333 /// assert_eq!(map.contains_second_key(&"b"), false);
334 /// ```
335 pub fn contains_second_key<Q: ?Sized>(&self, key: &Q) -> bool
336 where Kv2: Borrow<Q>,
337 Q : PartialEq<Kv2>,
338 {
339 self.cont.iter().any(|ref kvs| *key == kvs.1)
340 }
341
342 /// Returns a mutable reference to the second K/V corresponding to the first K/V.
343 ///
344 /// # Examples
345 ///
346 /// ```
347 /// use bidir_map::BidirMap;
348 ///
349 /// let mut map = BidirMap::new();
350 /// map.insert(1, "a");
351 /// if let Some(x) = map.get_mut_by_first(&1) {
352 /// *x = "b";
353 /// }
354 /// assert_eq!(map.get_by_first(&1), Some(&"b"));
355 /// ```
356 pub fn get_mut_by_first<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Kv2>
357 where Kv1: Borrow<Q>,
358 Q : PartialEq<Kv1>,
359 {
360 self.cont.iter_mut().find(|ref kvs| *key == kvs.0).map(|&mut (_, ref mut kv2)| kv2)
361 }
362
363 /// Returns a mutable reference to the first K/V corresponding to the second K/V.
364 ///
365 /// # Examples
366 ///
367 /// ```
368 /// use bidir_map::BidirMap;
369 ///
370 /// let mut map = BidirMap::new();
371 /// map.insert(1, "a");
372 /// if let Some(x) = map.get_mut_by_second(&"a") {
373 /// *x = 2;
374 /// }
375 /// assert_eq!(map.get_by_second(&"a"), Some(&2));
376 /// ```
377 pub fn get_mut_by_second<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Kv1>
378 where Kv2: Borrow<Q>,
379 Q : PartialEq<Kv2>,
380 {
381 self.cont.iter_mut().find(|ref kvs| *key == kvs.1).map(|&mut (ref mut kv1, _)| kv1)
382 }
383
384 /// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
385 ///
386 /// # Examples
387 ///
388 /// ```
389 /// use bidir_map::BidirMap;
390 ///
391 /// let mut map = BidirMap::new();
392 /// map.insert(1, "a");
393 /// assert_eq!(map.remove_by_first(&1), Some((1, "a")));
394 /// assert_eq!(map.remove_by_first(&1), None);
395 /// ```
396 pub fn remove_by_first<Q: ?Sized>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
397 where Kv1: Borrow<Q>,
398 Q : PartialEq<Kv1>,
399 {
400 self.cont.iter().position(|ref kvs| *key == kvs.0).map(|idx| self.cont.swap_remove(idx))
401 }
402
403 /// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
404 ///
405 /// # Examples
406 ///
407 /// ```
408 /// use bidir_map::BidirMap;
409 ///
410 /// let mut map = BidirMap::new();
411 /// map.insert(1, "a");
412 /// assert_eq!(map.remove_by_second(&"a"), Some((1, "a")));
413 /// assert_eq!(map.remove_by_second(&"b"), None);
414 /// ```
415 pub fn remove_by_second<Q: ?Sized>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
416 where Kv2: Borrow<Q>,
417 Q : PartialEq<Kv2>,
418 {
419 self.cont.iter().position(|ref kvs| *key == kvs.1).map(|idx| self.cont.swap_remove(idx))
420 }
421}
422
423
424impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
425 type Item = (Kv1, Kv2);
426 type IntoIter = vec::IntoIter<Self::Item>;
427
428 fn into_iter(self) -> Self::IntoIter {
429 return self.cont.into_iter()
430 }
431}
432
433impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
434 fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
435 BidirMap{
436 cont: Vec::from_iter(iter),
437 }
438 }
439}
440
441impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
442 fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
443 self.cont.extend(iter)
444 }
445}
446
447
448/// Wrapper type for getting second keys/values with first keys/values via `Index`.
449///
450/// To assume that by-first is the "default" would be incorrect, so thus you one can wrap their indices with this and all is swell.
451///
452/// # Examples
453///
454/// ```
455/// use bidir_map::{BidirMap, ByFirst};
456///
457/// let mut map = BidirMap::new();
458/// map.insert(1, "a");
459/// assert_eq!(map[ByFirst(&1)], "a");
460/// assert_eq!(map[&ByFirst(&1)], "a");
461/// ```
462#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
463pub struct ByFirst<'q, Q: ?Sized + 'q>(pub &'q Q);
464
465/// Wrapper type for getting second keys/values with first keys/values via `Index`.
466///
467/// # Examples
468///
469/// ```
470/// use bidir_map::{BidirMap, BySecond};
471///
472/// let mut map = BidirMap::new();
473/// map.insert(1, "a");
474/// assert_eq!(map[BySecond(&"a")], 1);
475/// assert_eq!(map[&BySecond(&"a")], 1);
476/// ```
477#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
478pub struct BySecond<'q, Q: ?Sized + 'q>(pub &'q Q);
479
480impl<'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<ByFirst<'q, Q>> for BidirMap<Kv1, Kv2>
481 where Kv1: Borrow<Q>,
482 Q : PartialEq<Kv1>,
483{
484 type Output = Kv2;
485 fn index(&self, key: ByFirst<Q>) -> &Self::Output {
486 self.get_by_first(&key.0).expect("no entry found for first key/value")
487 }
488}
489
490impl<'a, 'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<&'a ByFirst<'q, Q>> for BidirMap<Kv1, Kv2>
491 where Kv1: Borrow<Q>,
492 Q : PartialEq<Kv1>,
493{
494 type Output = Kv2;
495 fn index(&self, key: &ByFirst<Q>) -> &Self::Output {
496 self.get_by_first(&key.0).expect("no entry found for first key/value")
497 }
498}
499
500impl<'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<BySecond<'q, Q>> for BidirMap<Kv1, Kv2>
501 where Kv2: Borrow<Q>,
502 Q : PartialEq<Kv2>,
503{
504 type Output = Kv1;
505 fn index(&self, key: BySecond<Q>) -> &Self::Output {
506 self.get_by_second(&key.0).expect("no entry found for second key/value")
507 }
508}
509
510impl<'a, 'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<&'a BySecond<'q, Q>> for BidirMap<Kv1, Kv2>
511 where Kv2: Borrow<Q>,
512 Q : PartialEq<Kv2>,
513{
514 type Output = Kv1;
515 fn index(&self, key: &BySecond<Q>) -> &Self::Output {
516 self.get_by_second(&key.0).expect("no entry found for second key/value")
517 }
518}
519
520
521/// An iterator over the K/V pairs contained in a `BidirMap`.
522///
523/// See documentation of [`BidirMap::iter()`](struct.BidirMap.html#method.iter) for more.
524pub struct Iter<'a, Kv1: 'a, Kv2: 'a> {
525 iter: slice::Iter<'a, (Kv1, Kv2)>,
526}
527
528impl<'a, Kv1, Kv2> Iterator for Iter<'a, Kv1, Kv2> {
529 type Item = (&'a Kv1, &'a Kv2);
530 fn next(&mut self) -> Option<Self::Item> {
531 self.iter.next().map(|&(ref kv1, ref kv2)| (kv1, kv2))
532 }
533}
534
535
536/// An iterator over mutable K/V pairs contained in a `BidirMap`.
537///
538/// See documentation of [`BidirMap::iter_mut()`](struct.BidirMap.html#method.iter_mut) for more.
539pub struct IterMut<'a, Kv1: 'a, Kv2: 'a> {
540 iter: slice::IterMut<'a, (Kv1, Kv2)>,
541}
542
543impl<'a, Kv1, Kv2> Iterator for IterMut<'a, Kv1, Kv2> {
544 type Item = (&'a mut Kv1, &'a mut Kv2);
545 fn next(&mut self) -> Option<Self::Item> {
546 self.iter.next().map(|&mut (ref mut kv1, ref mut kv2)| (kv1, kv2))
547 }
548}
549
550
551/// An iterator the first set of K/Vs in a `BidirMap`.
552///
553/// See documentation of [`BidirMap::first_col()`](struct.BidirMap.html#method.first_col) for more.
554pub struct FirstColumn<'a, Kv1: 'a, Kv2: 'a> {
555 iter: slice::Iter<'a, (Kv1, Kv2)>,
556}
557
558impl<'a, Kv1, Kv2> Iterator for FirstColumn<'a, Kv1, Kv2> {
559 type Item = &'a Kv1;
560 fn next(&mut self) -> Option<Self::Item> {
561 self.iter.next().map(|ref kvs| &kvs.0)
562 }
563}
564
565
566/// An iterator the second set of K/Vs in a `BidirMap`.
567///
568/// See documentation of [`BidirMap::second_col()`](struct.BidirMap.html#method.second_col) for more.
569pub struct SecondColumn<'a, Kv1: 'a, Kv2: 'a> {
570 iter: slice::Iter<'a, (Kv1, Kv2)>,
571}
572
573impl<'a, Kv1, Kv2> Iterator for SecondColumn<'a, Kv1, Kv2> {
574 type Item = &'a Kv2;
575 fn next(&mut self) -> Option<Self::Item> {
576 self.iter.next().map(|ref kvs| &kvs.1)
577 }
578}