use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct ProxyRotator {
proxies: Arc<Vec<String>>,
cursor: Arc<AtomicUsize>,
}
impl ProxyRotator {
pub fn new(proxies: Vec<String>) -> Option<Self> {
if proxies.is_empty() {
return None;
}
Some(Self {
proxies: Arc::new(proxies),
cursor: Arc::new(AtomicUsize::new(0)),
})
}
#[must_use]
pub fn next(&self) -> &str {
&self.proxies[self.next_index()]
}
#[must_use]
pub fn next_index(&self) -> usize {
self.cursor.fetch_add(1, Ordering::Relaxed) % self.proxies.len()
}
#[must_use]
pub fn random(&self) -> &str {
let pos = self.cursor.fetch_add(1, Ordering::Relaxed);
let idx = pos.wrapping_mul(2654435761).wrapping_add(1013904223) % self.proxies.len();
&self.proxies[idx]
}
#[must_use]
pub fn len(&self) -> usize {
self.proxies.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.proxies.is_empty()
}
}