use futures::Stream;
use rand::{CryptoRng, RngExt};
use alloc::{boxed::Box, string::String, vec::Vec};
use core::{
fmt,
future::Future,
net::SocketAddr,
pin::Pin,
task::{Context, Poll},
time::Duration,
};
#[cfg(test)]
pub mod mock;
#[cfg(test)]
pub mod noop;
pub trait AsyncRead {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<crate::Result<usize>>;
}
pub trait AsyncWrite {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<crate::Result<usize>>;
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<crate::Result<()>>;
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<crate::Result<()>>;
}
pub trait TcpStream: AsyncRead + AsyncWrite + Unpin + Send + Sync + Sized + 'static {
fn connect(address: SocketAddr) -> impl Future<Output = Option<Self>> + Send;
}
pub trait TcpListener<TcpStream>: Unpin + Send + Sized + 'static {
fn bind(address: SocketAddr) -> impl Future<Output = Option<Self>>;
fn poll_accept(&mut self, cx: &mut Context<'_>) -> Poll<Option<(TcpStream, SocketAddr)>>;
fn local_address(&self) -> Option<SocketAddr>;
}
pub trait UdpSocket: Unpin + Send + Sized + Clone {
fn bind(address: SocketAddr) -> impl Future<Output = Option<Self>>;
fn bind_with_mtu(address: SocketAddr, mtu: usize) -> impl Future<Output = Option<Self>>;
fn send_to(
&mut self,
buf: &[u8],
target: SocketAddr,
) -> impl Future<Output = Option<usize>> + Send;
fn recv_from(
&mut self,
buf: &mut [u8],
) -> impl Future<Output = Option<(usize, SocketAddr)>> + Send;
fn poll_send_to(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
target: SocketAddr,
) -> Poll<Option<usize>>;
fn poll_recv_from(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Option<(usize, SocketAddr)>>;
fn local_address(&self) -> Option<SocketAddr>;
fn mtu(&self) -> usize;
}
pub trait JoinSet<T>: Stream<Item = T> + Unpin + Send {
fn is_empty(&self) -> bool;
fn len(&self) -> usize;
fn push<F>(&mut self, future: F)
where
F: Future<Output = T> + Send + 'static,
F::Output: Send;
}
pub trait Instant: fmt::Debug + Copy + Clone + Send + Unpin + Sync {
fn elapsed(&self) -> Duration;
}
pub trait Counter {
fn increment(&mut self, value: usize);
fn increment_with_label(
&mut self,
value: usize,
label_name: &'static str,
label_value: &'static str,
);
}
pub trait Gauge {
fn increment(&mut self, value: usize);
fn decrement(&mut self, value: usize);
}
pub trait Histogram {
fn record(&mut self, record: f64);
}
pub trait MetricsHandle: Clone + Send + Sync + Unpin {
fn counter(&self, name: &'static str) -> impl Counter;
fn gauge(&self, name: &'static str) -> impl Gauge;
fn histogram(&self, name: &'static str) -> impl Histogram;
}
pub enum MetricType {
Counter {
name: &'static str,
description: &'static str,
},
Gauge {
name: &'static str,
description: &'static str,
},
Histogram {
name: &'static str,
description: &'static str,
buckets: Vec<f64>,
},
}
pub trait Runtime: Clone + Unpin + Send + 'static {
type TcpStream: TcpStream;
type UdpSocket: UdpSocket;
type TcpListener: TcpListener<Self::TcpStream>;
type JoinSet<T: Send + 'static>: JoinSet<T>;
type MetricsHandle: MetricsHandle;
type Instant: Instant;
type Timer: Future<Output = ()> + Send + Unpin;
fn spawn<F>(future: F)
where
F: Future + Send + 'static,
F::Output: Send;
fn time_since_epoch() -> Duration;
fn now() -> Self::Instant;
fn rng() -> impl CryptoRng + RngExt;
fn join_set<T: Send + 'static>() -> Self::JoinSet<T>;
fn register_metrics(metrics: Vec<MetricType>, port: Option<u16>) -> Self::MetricsHandle;
fn timer(duration: Duration) -> Self::Timer;
fn delay(duration: Duration) -> impl Future<Output = ()> + Send;
fn gzip_compress(bytes: impl AsRef<[u8]>) -> Option<Vec<u8>>;
fn gzip_decompress(bytes: impl AsRef<[u8]>) -> Option<Vec<u8>>;
}
pub trait AddressBook: Unpin + Send + Sync + 'static {
fn resolve_base64(&self, host: String) -> Pin<Box<dyn Future<Output = Option<String>> + Send>>;
fn resolve_base32(&self, host: &str) -> Option<String>;
}
pub trait Storage: Unpin + Send + Sync + 'static {
fn save_to_disk(&self, routers: Vec<(String, Option<Vec<u8>>, crate::Profile)>);
}