use crate::{errors::EasyHttpMockError, mock::Mock};
use once_cell::sync::OnceCell;
use std::{
collections::HashSet,
future::Future,
sync::{Arc, Mutex},
};
static PORTS_IN_USE: OnceCell<Mutex<HashSet<u16>>> = OnceCell::new();
pub trait ServerAdapter {
type Config: Clone;
fn new(config: Self::Config) -> Result<Self, EasyHttpMockError>
where
Self: Sized;
fn hostname(&self) -> String;
fn base_url(&self) -> String;
fn config(&self) -> &Self::Config;
fn config_mut(&mut self) -> &mut Self::Config;
fn register_mock(&mut self, mock: Arc<Mock>);
fn start(&mut self) -> impl Future<Output = Result<(), EasyHttpMockError>>;
fn stop(&mut self) -> impl Future<Output = Result<(), EasyHttpMockError>>;
}
pub trait PortGenerator<S>
where
S: ServerAdapter,
S::Config: Clone,
{
fn random_port() -> u16 {
generate_randon_port()
}
fn with_random_port(self) -> Self;
}
pub fn generate_randon_port() -> u16 {
let ports = PORTS_IN_USE.get_or_init(|| Mutex::new(HashSet::new()));
match ports.lock() {
Ok(mut ports) => {
let mut port = rand::random_range(9000..65535);
while ports.contains(&port) {
port = rand::random_range(9000..65535);
}
ports.insert(port);
port
}
Err(_) => rand::random_range(9000..65535),
}
}