use core::{net::{Ipv4Addr, Ipv6Addr, SocketAddr}, task::{Poll, Context}, time::Duration};
use rustls::{ClientConfig, CommonState, ServerConfig, pki_types::ServerName};
#[cfg(feature = "std")]
use std::sync::Arc;
#[cfg(not(feature = "std"))]
use alloc::sync::Arc;
#[cfg(feature = "tokio")]
mod tokio;
#[cfg(feature = "tokio")]
pub use tokio::TokioIoImpl;
pub use rustls;
use crate::{error::Result, device::Device};
#[derive(Debug)]
pub enum KnownFunctionName<TcpStream: TcpStreamImpl> {
SetupUdp,
SetupMdns,
PerTcpStream(TcpStream),
}
pub trait UdpSocketImpl {
fn set_broadcast(&self, on: bool) -> Result<()>;
fn poll_recv(&self, cx: &mut Context, buf: &mut [u8]) -> Poll<Result<()>>;
fn recv_from(&self, buf: &mut [u8]) -> impl Future<Output = Result<(usize, SocketAddr)>>;
fn send_to(&mut self, buf: &[u8], addr: SocketAddr) -> impl Future<Output = Result<usize>>;
}
pub trait TcpStreamImpl {
fn read(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<usize>>;
fn writable(&self) -> impl Future<Output = Result<()>>;
fn write_all(&mut self, src: &[u8]) -> impl Future<Output = Result<()>>;
}
pub trait TcpListenerImpl<TcpStream: TcpStreamImpl> {
fn accept(&self) -> impl Future<Output = Result<TcpStream>>;
}
pub trait TlsStreamImpl {
fn get_common_state(&self) -> &CommonState;
fn read(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<usize>>;
fn write_all(&mut self, src: &[u8]) -> impl Future<Output = Result<()>>;
}
pub trait IoImpl<UdpSocket: UdpSocketImpl, TcpStream: TcpStreamImpl, TcpListener: TcpListenerImpl<TcpStream>, TlsStream: TlsStreamImpl> where Self: Sized {
fn bind_udp(&self, addr: SocketAddr) -> impl Future<Output = Result<UdpSocket>>;
fn bind_udp_reuse_v6(&self, addr: SocketAddr) -> impl Future<Output = Result<UdpSocket>>;
fn bind_udp_reuse_multicast_v4(&self, addr: SocketAddr, multicast_addr: (Ipv4Addr, Ipv4Addr)) -> impl Future<Output = Result<UdpSocket>>;
fn listen_tcp(&self, addr: SocketAddr) -> impl Future<Output = Result<TcpListener>>;
fn connect_tcp(&self, addr: SocketAddr) -> impl Future<Output = Result<TcpStream>>;
fn accept_server_tls(&self, config: ServerConfig, stream: TcpStream) -> impl Future<Output = Result<TlsStream>>;
fn connect_client_tls(&self, config: ClientConfig, server_name: ServerName<'static>, stream: TcpStream) -> impl Future<Output = Result<TlsStream>>;
fn get_host_addresses(&self) -> impl Future<Output = (Option<Ipv4Addr>, Option<Ipv6Addr>)>;
fn sleep(&self, duration: Duration) -> impl Future<Output = ()>;
fn spawn(&self, name: KnownFunctionName<TcpStream>, device: Arc<Device<Self, UdpSocket, TcpStream, TcpListener, TlsStream>>);
fn start(&self, device: Arc<Device<Self, UdpSocket, TcpStream, TcpListener, TlsStream>>);
fn get_current_timestamp(&self) -> impl Future<Output = u64>;
}