use std::borrow::Borrow;
use std::slice;
use std::iter::{Extend, FromIterator};
use std::ops::Index;
use std::vec;
#[macro_export]
macro_rules! bidir_map {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(bidir_map!(@single $rest)),*]));
($($key:expr => $value:expr,)+) => { bidir_map!($($key => $value),+) };
($($key:expr => $value:expr),*) => {{
let cap = bidir_map!(@count $($key),*);
let mut map = ::bidir_map::BidirMap::with_capacity(cap);
$(map.insert($key, $value);)*
map
}};
}
#[derive(Default, Clone, Debug, Hash, PartialEq, Eq)]
pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
cont: Vec<(Kv1, Kv2)>,
}
impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
pub fn new() -> Self {
BidirMap{
cont: Vec::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
BidirMap{
cont: Vec::with_capacity(capacity),
}
}
pub fn clear(&mut self) {
self.cont.clear()
}
pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) -> Option<(Kv1, Kv2)> {
let retval =
if self.contains_first_key(&kv1) {
self.remove_by_first(&kv1)
} else if self.contains_second_key(&kv2) {
self.remove_by_second(&kv2)
} else {
None
};
self.cont.push((kv1, kv2));
retval
}
pub fn iter(&self) -> Iter<Kv1, Kv2> {
Iter{
iter: self.cont.iter(),
}
}
pub fn iter_mut(&mut self) -> IterMut<Kv1, Kv2> {
IterMut{
iter: self.cont.iter_mut(),
}
}
pub fn first_col(&self) -> FirstColumn<Kv1, Kv2> {
FirstColumn{
iter: self.cont.iter(),
}
}
pub fn second_col(&self) -> SecondColumn<Kv1, Kv2> {
SecondColumn{
iter: self.cont.iter(),
}
}
pub fn len(&self) -> usize {
self.cont.len()
}
pub fn is_empty(&self) -> bool {
self.cont.is_empty()
}
pub fn get_by_first<Q: ?Sized>(&self, key: &Q) -> Option<&Kv2>
where Kv1: Borrow<Q>,
Q : PartialEq<Kv1>,
{
self.cont.iter().find(|&kvs| *key == kvs.0).map(|ref kvs| &kvs.1)
}
pub fn get_by_second<Q: ?Sized>(&self, key: &Q) -> Option<&Kv1>
where Kv2: Borrow<Q>,
Q : PartialEq<Kv2>,
{
self.cont.iter().find(|&kvs| *key == kvs.1).map(|ref kvs| &kvs.0)
}
pub fn contains_first_key<Q: ?Sized>(&self, key: &Q) -> bool
where Kv1: Borrow<Q>,
Q : PartialEq<Kv1>,
{
self.cont.iter().any(|ref kvs| *key == kvs.0)
}
pub fn contains_second_key<Q: ?Sized>(&self, key: &Q) -> bool
where Kv2: Borrow<Q>,
Q : PartialEq<Kv2>,
{
self.cont.iter().any(|ref kvs| *key == kvs.1)
}
pub fn get_mut_by_first<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Kv2>
where Kv1: Borrow<Q>,
Q : PartialEq<Kv1>,
{
self.cont.iter_mut().find(|ref kvs| *key == kvs.0).map(|&mut (_, ref mut kv2)| kv2)
}
pub fn get_mut_by_second<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Kv1>
where Kv2: Borrow<Q>,
Q : PartialEq<Kv2>,
{
self.cont.iter_mut().find(|ref kvs| *key == kvs.1).map(|&mut (ref mut kv1, _)| kv1)
}
pub fn remove_by_first<Q: ?Sized>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
where Kv1: Borrow<Q>,
Q : PartialEq<Kv1>,
{
self.cont.iter().position(|ref kvs| *key == kvs.0).map(|idx| self.cont.swap_remove(idx))
}
pub fn remove_by_second<Q: ?Sized>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
where Kv2: Borrow<Q>,
Q : PartialEq<Kv2>,
{
self.cont.iter().position(|ref kvs| *key == kvs.1).map(|idx| self.cont.swap_remove(idx))
}
}
impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
type Item = (Kv1, Kv2);
type IntoIter = vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
return self.cont.into_iter()
}
}
impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
BidirMap{
cont: Vec::from_iter(iter),
}
}
}
impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
self.cont.extend(iter)
}
}
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct ByFirst<'q, Q: ?Sized + 'q>(pub &'q Q);
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct BySecond<'q, Q: ?Sized + 'q>(pub &'q Q);
impl<'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<ByFirst<'q, Q>> for BidirMap<Kv1, Kv2>
where Kv1: Borrow<Q>,
Q : PartialEq<Kv1>,
{
type Output = Kv2;
fn index(&self, key: ByFirst<Q>) -> &Self::Output {
self.get_by_first(&key.0).expect("no entry found for first key/value")
}
}
impl<'a, 'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<&'a ByFirst<'q, Q>> for BidirMap<Kv1, Kv2>
where Kv1: Borrow<Q>,
Q : PartialEq<Kv1>,
{
type Output = Kv2;
fn index(&self, key: &ByFirst<Q>) -> &Self::Output {
self.get_by_first(&key.0).expect("no entry found for first key/value")
}
}
impl<'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<BySecond<'q, Q>> for BidirMap<Kv1, Kv2>
where Kv2: Borrow<Q>,
Q : PartialEq<Kv2>,
{
type Output = Kv1;
fn index(&self, key: BySecond<Q>) -> &Self::Output {
self.get_by_second(&key.0).expect("no entry found for second key/value")
}
}
impl<'a, 'q, Kv1: PartialEq, Kv2: PartialEq, Q: ?Sized + 'q> Index<&'a BySecond<'q, Q>> for BidirMap<Kv1, Kv2>
where Kv2: Borrow<Q>,
Q : PartialEq<Kv2>,
{
type Output = Kv1;
fn index(&self, key: &BySecond<Q>) -> &Self::Output {
self.get_by_second(&key.0).expect("no entry found for second key/value")
}
}
pub struct Iter<'a, Kv1: 'a, Kv2: 'a> {
iter: slice::Iter<'a, (Kv1, Kv2)>,
}
impl<'a, Kv1, Kv2> Iterator for Iter<'a, Kv1, Kv2> {
type Item = (&'a Kv1, &'a Kv2);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|&(ref kv1, ref kv2)| (kv1, kv2))
}
}
pub struct IterMut<'a, Kv1: 'a, Kv2: 'a> {
iter: slice::IterMut<'a, (Kv1, Kv2)>,
}
impl<'a, Kv1, Kv2> Iterator for IterMut<'a, Kv1, Kv2> {
type Item = (&'a mut Kv1, &'a mut Kv2);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|&mut (ref mut kv1, ref mut kv2)| (kv1, kv2))
}
}
pub struct FirstColumn<'a, Kv1: 'a, Kv2: 'a> {
iter: slice::Iter<'a, (Kv1, Kv2)>,
}
impl<'a, Kv1, Kv2> Iterator for FirstColumn<'a, Kv1, Kv2> {
type Item = &'a Kv1;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|ref kvs| &kvs.0)
}
}
pub struct SecondColumn<'a, Kv1: 'a, Kv2: 'a> {
iter: slice::Iter<'a, (Kv1, Kv2)>,
}
impl<'a, Kv1, Kv2> Iterator for SecondColumn<'a, Kv1, Kv2> {
type Item = &'a Kv2;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|ref kvs| &kvs.1)
}
}