You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.2 KiB
51 lines
1.2 KiB
use std::collections::hash_map::Entry;
|
|
use std::collections::HashMap;
|
|
use std::hash::Hash;
|
|
|
|
pub struct AddressMap<K, A> {
|
|
inner: HashMap<K, xtra::Address<A>>,
|
|
}
|
|
|
|
impl<K, A> Default for AddressMap<K, A> {
|
|
fn default() -> Self {
|
|
Self {
|
|
inner: HashMap::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<K, A> AddressMap<K, A>
|
|
where
|
|
K: Eq + Hash,
|
|
{
|
|
pub fn get_disconnected(&mut self, key: K) -> Result<Disconnected<'_, K, A>, StillConnected> {
|
|
let entry = self.inner.entry(key);
|
|
|
|
if matches!(entry, Entry::Occupied(ref occupied) if occupied.get().is_connected()) {
|
|
return Err(StillConnected);
|
|
}
|
|
|
|
Ok(Disconnected { entry })
|
|
}
|
|
}
|
|
|
|
#[derive(thiserror::Error, Debug)]
|
|
#[error("The address is still connected")]
|
|
pub struct StillConnected;
|
|
|
|
pub struct Disconnected<'a, K, A> {
|
|
entry: Entry<'a, K, xtra::Address<A>>,
|
|
}
|
|
|
|
impl<'a, K, A> Disconnected<'a, K, A> {
|
|
pub fn insert(self, address: xtra::Address<A>) {
|
|
match self.entry {
|
|
Entry::Occupied(mut occ) => {
|
|
occ.insert(address);
|
|
}
|
|
Entry::Vacant(vacc) => {
|
|
vacc.insert(address);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|