use std::cell::RefCell;
use std::collections::HashSet;
use std::hash::Hash;
use std::rc::Rc;
use error::{Error, ErrorKind};
pub struct Reservations<K>
where
K: Eq + Hash,
{
reserved: Rc<RefCell<HashSet<K>>>,
}
impl<K> Reservations<K>
where
K: Eq + Hash + Clone,
{
pub fn new() -> Reservations<K> {
Reservations {
reserved: Rc::new(RefCell::new(HashSet::new())),
}
}
pub fn is_reserved(&self, key: &K) -> bool {
let reserved = self.reserved.borrow();
reserved.contains(key)
}
pub fn try_reserve(&self, key: K) -> Result<Reservation<K>, Error> {
let mut reserved = self.reserved.borrow_mut();
if reserved.insert(key.clone()) {
Ok(Reservation {
key,
reserved: Rc::clone(&self.reserved),
})
} else {
Err(Error::new(ErrorKind::Reserved))
}
}
}
pub struct Reservation<K>
where
K: Eq + Hash,
{
key: K,
reserved: Rc<RefCell<HashSet<K>>>,
}
impl<K> Drop for Reservation<K>
where
K: Eq + Hash,
{
fn drop(&mut self) {
let mut reserved = self.reserved.borrow_mut();
reserved.take(&self.key).unwrap();
}
}