use async_std::sync::Mutex; use rand::seq::SliceRandom; use std::{collections::HashSet, net::SocketAddr, sync::Arc}; /// Pointer to hosts class. pub type HostsPtr = Arc; /// Manages a store of network addresses. pub struct Hosts { addrs: Mutex>, } impl Hosts { /// Create a new host list. pub fn new() -> Arc { Arc::new(Self { addrs: Mutex::new(Vec::new()) }) } /// Checks if a host address is in the host list. async fn contains(&self, addrs: &[SocketAddr]) -> bool { let a_set: HashSet<_> = addrs.iter().copied().collect(); self.addrs.lock().await.iter().any(|item| a_set.contains(item)) } /// Add a new host to the host list. pub async fn store(&self, addrs: Vec) { if !self.contains(&addrs).await { self.addrs.lock().await.extend(addrs) } } /// Return a single host address. pub async fn load_single(&self) -> Option { self.addrs.lock().await.choose(&mut rand::thread_rng()).cloned() } /// Return the list of hosts. pub async fn load_all(&self) -> Vec { self.addrs.lock().await.clone() } /// Check if the host list is empty. pub async fn is_empty(&self) -> bool { self.addrs.lock().await.is_empty() } }