use super::*;
use futures::prelude::*;
use futures::task::Context;
use futures::Poll;
use std::pin::Pin;
pub trait AsyncDatagramSocket:
DatagramSocketTypes + AsyncSendTo + AsyncRecvFrom + MulticastSocket + Send + Sync
{
}
pub trait DatagramSocketTypes: Unpin {
type SocketAddr: SocketAddrExt
+ core::fmt::Display
+ core::fmt::Debug
+ std::string::ToString
+ ToSocketAddrs<SocketAddr = Self::SocketAddr, Error = Self::Error>
+ Send
+ Unpin
+ Copy;
type Error: std::fmt::Display + std::fmt::Debug;
fn local_addr(&self) -> Result<Self::SocketAddr, Self::Error>;
fn lookup_host(
host: &str,
port: u16,
) -> Result<std::vec::IntoIter<Self::SocketAddr>, Self::Error>
where
Self: Sized;
}
pub trait AsyncSendTo: DatagramSocketTypes {
fn poll_send_to<B>(
self: Pin<&Self>,
cx: &mut Context<'_>,
buf: &[u8],
addr: B,
) -> Poll<Result<usize, Self::Error>>
where
B: super::ToSocketAddrs<SocketAddr = Self::SocketAddr, Error = Self::Error>;
fn next_send_to<'a, 'b, B>(&'a self, buf: &'b [u8], addr: B) -> NextSendToFuture<'a, 'b, Self>
where
B: super::ToSocketAddrs<SocketAddr = Self::SocketAddr, Error = Self::Error>,
{
let addr = addr.to_socket_addrs().unwrap().next().unwrap();
NextSendToFuture {
socket: self,
buffer: buf,
addr: addr,
}
}
fn send_to<B>(&self, buf: &[u8], addr: B) -> Result<usize, Self::Error>
where
B: super::ToSocketAddrs<SocketAddr = Self::SocketAddr, Error = Self::Error>,
{
self.next_send_to(buf, addr)
.now_or_never()
.expect("send_to blocked")
}
}
#[derive(Debug)]
pub struct NextSendToFuture<'a, 'b, T>
where
T: DatagramSocketTypes + AsyncSendTo + ?Sized,
{
socket: &'a T,
buffer: &'b [u8],
addr: T::SocketAddr,
}
impl<'a, 'b, T> NextSendToFuture<'a, 'b, T>
where
T: DatagramSocketTypes + AsyncSendTo + ?Sized,
{
fn poll_unpin(
self: &mut Self,
cx: &mut futures::task::Context<'_>,
) -> futures::task::Poll<Result<usize, T::Error>> {
Pin::new(self.socket).poll_send_to(cx, self.buffer, self.addr.clone())
}
}
impl<'a, 'b, T> Future for NextSendToFuture<'a, 'b, T>
where
T: DatagramSocketTypes + AsyncSendTo + ?Sized,
{
type Output = Result<usize, T::Error>;
fn poll(
self: Pin<&mut Self>,
cx: &mut futures::task::Context<'_>,
) -> futures::task::Poll<Self::Output> {
self.get_mut().poll_unpin(cx)
}
}
#[derive(Debug)]
pub struct NextRecvFromFuture<'a, 'b, T: AsyncRecvFrom + ?Sized> {
socket: &'a T,
buffer: &'b mut [u8],
}
impl<'a, 'b, T: AsyncRecvFrom + ?Sized + Unpin> NextRecvFromFuture<'a, 'b, T> {
fn poll_unpin(
self: &mut Self,
cx: &mut futures::task::Context<'_>,
) -> futures::task::Poll<Result<(usize, T::SocketAddr, Option<T::SocketAddr>), T::Error>> {
Pin::new(self.socket).poll_recv_from(cx, self.buffer)
}
}
impl<'a, 'b, T: AsyncRecvFrom + ?Sized> Future for NextRecvFromFuture<'a, 'b, T> {
type Output = Result<(usize, T::SocketAddr, Option<T::SocketAddr>), T::Error>;
fn poll(
self: Pin<&mut Self>,
cx: &mut futures::task::Context<'_>,
) -> futures::task::Poll<Self::Output> {
self.get_mut().poll_unpin(cx)
}
}
pub trait AsyncRecvFrom: DatagramSocketTypes {
fn poll_recv_from(
self: Pin<&Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<(usize, Self::SocketAddr, Option<Self::SocketAddr>), Self::Error>>;
fn next_recv_from<'a, 'b>(&'a self, buf: &'b mut [u8]) -> NextRecvFromFuture<'a, 'b, Self> {
NextRecvFromFuture {
socket: self,
buffer: buf,
}
}
}
pub trait MulticastSocket: DatagramSocketTypes {
type IpAddr;
fn join_multicast<A>(&self, addr: A) -> Result<(), Self::Error>
where
A: std::convert::Into<Self::IpAddr>;
fn leave_multicast<A>(&self, addr: A) -> Result<(), Self::Error>
where
A: std::convert::Into<Self::IpAddr>;
}