use futures_lite::{AsyncRead, AsyncWrite};
use std::{
io::Result,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
os::fd::{AsFd, AsRawFd},
};
pub enum SocketAddrsKind<'a> {
Slice(&'a [SocketAddr]),
StrPort(&'a str, u16),
IpAddr(IpAddr, u16),
Ipv4Addr(Ipv4Addr, u16),
Ipv6Addr(Ipv6Addr, u16),
Str(&'a str),
SocketAddr(&'a SocketAddr),
SocketAddrV4(&'a SocketAddrV4),
SocketAddrV6(&'a SocketAddrV6),
}
pub trait ToSocketAddrs {
fn kind(&self) -> SocketAddrsKind<'_>;
}
impl ToSocketAddrs for &[SocketAddr] {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::Slice(self)
}
}
impl ToSocketAddrs for (&str, u16) {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::StrPort(self.0, self.1)
}
}
impl ToSocketAddrs for (IpAddr, u16) {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::IpAddr(self.0, self.1)
}
}
impl ToSocketAddrs for (String, u16) {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::StrPort(&self.0, self.1)
}
}
impl ToSocketAddrs for (Ipv4Addr, u16) {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::Ipv4Addr(self.0, self.1)
}
}
impl ToSocketAddrs for (Ipv6Addr, u16) {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::Ipv6Addr(self.0, self.1)
}
}
impl ToSocketAddrs for str {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::Str(self)
}
}
impl ToSocketAddrs for String {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::Str(self)
}
}
impl ToSocketAddrs for SocketAddr {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::SocketAddr(self)
}
}
impl ToSocketAddrs for SocketAddrV4 {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::SocketAddrV4(self)
}
}
impl ToSocketAddrs for SocketAddrV6 {
fn kind(&self) -> SocketAddrsKind<'_> {
SocketAddrsKind::SocketAddrV6(self)
}
}
impl<T: ToSocketAddrs> ToSocketAddrs for &T {
fn kind(&self) -> SocketAddrsKind<'_> {
(*self).kind()
}
}
pub trait TcpStream: AsyncRead + AsyncWrite + AsRawFd + Sized {
fn connect(addr: impl ToSocketAddrs) -> impl Future<Output = Result<Self>>;
fn local_addr(&self) -> Result<SocketAddr>;
fn nodelay(&self) -> Result<bool>;
fn peek(&self, buf: &mut [u8]) -> impl Future<Output = Result<usize>>;
fn peer_addr(&self) -> Result<SocketAddr>;
fn set_nodelay(&self, nodelay: bool) -> Result<()>;
fn set_ttl(&self, ttl: u32) -> Result<()>;
fn ttl(&self) -> Result<u32>;
}
pub trait TcpListener: AsFd + AsRawFd + Sized {
fn accept(&self) -> impl Future<Output = Result<(impl TcpStream, SocketAddr)>>;
fn bind(addr: impl ToSocketAddrs) -> impl Future<Output = Result<Self>>;
fn local_addr(&self) -> Result<SocketAddr>;
fn set_ttl(&self, ttl: u32) -> Result<()>;
fn ttl(&self) -> Result<u32>;
}
pub trait UdpSocket: AsFd + AsRawFd + Sized {
fn bind(addr: impl ToSocketAddrs) -> impl Future<Output = Result<Self>>;
fn broadcast(&self) -> Result<bool>;
fn connect(&self, addr: impl ToSocketAddrs) -> impl Future<Output = Result<()>>;
fn join_multicast_v4(&self, multiaddr: Ipv4Addr, interface: Ipv4Addr) -> Result<()>;
fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> Result<()>;
fn leave_multicast_v4(&self, multiaddr: Ipv4Addr, interface: Ipv4Addr) -> Result<()>;
fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> Result<()>;
fn local_addr(&self) -> Result<SocketAddr>;
fn multicast_loop_v4(&self) -> Result<bool>;
fn multicast_loop_v6(&self) -> Result<bool>;
fn multicast_ttl_v4(&self) -> Result<u32>;
fn peek(&self, buf: &mut [u8]) -> impl Future<Output = Result<usize>>;
fn peek_from(&self, buf: &mut [u8]) -> impl Future<Output = Result<(usize, SocketAddr)>>;
fn peer_addr(&self) -> Result<SocketAddr>;
fn recv(&self, buf: &mut [u8]) -> impl Future<Output = Result<usize>>;
fn recv_from(&self, buf: &mut [u8]) -> impl Future<Output = Result<(usize, SocketAddr)>>;
fn send(&self, buf: &[u8]) -> impl Future<Output = Result<usize>>;
fn send_to(&self, buf: &[u8], addr: impl ToSocketAddrs) -> impl Future<Output = Result<usize>>;
fn set_broadcast(&self, on: bool) -> Result<()>;
fn set_multicast_loop_v4(&self, on: bool) -> Result<()>;
fn set_multicast_loop_v6(&self, on: bool) -> Result<()>;
fn set_multicast_ttl_v4(&self, ttl: u32) -> Result<()>;
fn set_ttl(&self, ttl: u32) -> Result<()>;
fn ttl(&self) -> Result<u32>;
}
pub trait RuntimeNet {
type TcpStream: TcpStream;
type TcpListener: TcpListener;
type UdpSocket: UdpSocket;
fn get_socket_addrs(kind: SocketAddrsKind) -> impl Future<Output = Result<Vec<SocketAddr>>>;
}