use async_trait::async_trait;
use futures::stream;
use futures::task::Spawn;
use futures::{AsyncRead, AsyncWrite, Future};
use std::fmt::Debug;
use std::io::Result as IoResult;
use std::net::SocketAddr;
use std::time::{Duration, Instant, SystemTime};
pub trait Runtime:
Sync
+ Send
+ Spawn
+ BlockOn
+ Clone
+ SleepProvider
+ TcpProvider
+ TlsProvider<Self::TcpStream>
+ UdpProvider
+ Debug
+ 'static
{
}
impl<T> Runtime for T where
T: Sync
+ Send
+ Spawn
+ BlockOn
+ Clone
+ SleepProvider
+ TcpProvider
+ TlsProvider<Self::TcpStream>
+ UdpProvider
+ Debug
+ 'static
{
}
pub trait SleepProvider: Clone + Send + Sync + 'static {
type SleepFuture: Future<Output = ()> + Send + 'static;
#[must_use = "sleep() returns a future, which does nothing unless used"]
fn sleep(&self, duration: Duration) -> Self::SleepFuture;
fn now(&self) -> Instant {
Instant::now()
}
fn wallclock(&self) -> SystemTime {
SystemTime::now()
}
fn block_advance<T: Into<String>>(&self, _reason: T) {}
fn release_advance<T: Into<String>>(&self, _reason: T) {}
fn allow_one_advance(&self, _dur: Duration) {}
}
pub trait BlockOn: Clone + Send + Sync + 'static {
fn block_on<F: Future>(&self, future: F) -> F::Output;
}
#[async_trait]
pub trait TcpProvider: Clone + Send + Sync + 'static {
type TcpStream: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static;
type TcpListener: TcpListener<TcpStream = Self::TcpStream> + Send + Sync + Unpin + 'static;
async fn connect(&self, addr: &SocketAddr) -> IoResult<Self::TcpStream>;
async fn listen(&self, addr: &SocketAddr) -> IoResult<Self::TcpListener>;
}
#[async_trait]
pub trait TcpListener {
type TcpStream: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static;
type Incoming: stream::Stream<Item = IoResult<(Self::TcpStream, SocketAddr)>> + Send + Unpin;
async fn accept(&self) -> IoResult<(Self::TcpStream, SocketAddr)>;
fn incoming(self) -> Self::Incoming;
fn local_addr(&self) -> IoResult<SocketAddr>;
}
#[async_trait]
pub trait UdpProvider: Clone + Send + Sync + 'static {
type UdpSocket: UdpSocket + Send + Sync + Unpin + 'static;
async fn bind(&self, addr: &SocketAddr) -> IoResult<Self::UdpSocket>;
}
#[async_trait]
pub trait UdpSocket {
async fn recv(&self, buf: &mut [u8]) -> IoResult<(usize, SocketAddr)>;
async fn send(&self, buf: &[u8], target: &SocketAddr) -> IoResult<usize>;
fn local_addr(&self) -> IoResult<SocketAddr>;
}
pub trait CertifiedConn {
fn peer_certificate(&self) -> IoResult<Option<Vec<u8>>>;
}
#[async_trait]
pub trait TlsConnector<S> {
type Conn: AsyncRead + AsyncWrite + CertifiedConn + Unpin + Send + 'static;
async fn negotiate_unvalidated(&self, stream: S, sni_hostname: &str) -> IoResult<Self::Conn>;
}
pub trait TlsProvider<S>: Clone + Send + Sync + 'static {
type Connector: TlsConnector<S, Conn = Self::TlsStream> + Send + Sync + Unpin;
type TlsStream: AsyncRead + AsyncWrite + CertifiedConn + Unpin + Send + 'static;
fn tls_connector(&self) -> Self::Connector;
}