swindon 0.7.8

An HTTP edge (frontend) server with smart websockets support
use std::collections::{HashMap, HashSet};
use std::hash::Hash;


pub trait PairCollection<A, B> {
    fn insert_clone(&mut self, key1: &A, key2: &B)
        where A: Clone, B: Clone;
    fn insert_list_key1<'x, I>(&mut self, key1list: I, key2: &B)
        where I: IntoIterator<Item=&'x A>,
              A: Clone + 'x,
              B: Clone
    {
        for key1 in key1list {
            self.insert_clone(key1, key2);
        }
    }
    fn remove(&mut self, key1: &A, key2: &B);
    fn remove_list_key1<'x, I>(&mut self, key1list: I, key2: &B)
        where I: IntoIterator<Item=&'x A>,
              A: 'x
    {
        for key1 in key1list {
            self.remove(key1, key2);
        }
    }
}

impl<A, B> PairCollection<A, B> for HashMap<A, HashSet<B>>
    where A: Eq + Hash,
          B: Eq + Hash,
{
    fn insert_clone(&mut self, key1: &A, key2: &B)
        where A: Clone, B: Clone
    {
        self.entry(key1.clone())
            .or_insert_with(HashSet::new)
            .insert(key2.clone());
    }
    fn remove(&mut self, key1: &A, key2: &B) {
        let len = if let Some(sub) = self.get_mut(key1) {
            sub.remove(key2);
            sub.len()
        } else {
            return;
        };
        if len == 0 {
            self.remove(key1);
        }
    }
}