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}