use crate::error::{Error, Result};
use std::{
net::SocketAddr,
pin::Pin,
task::{Context, Poll},
};
#[derive(Clone, Copy, Debug)]
pub struct UdpServer<'a> {
socket: &'a tokio::net::UdpSocket,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Request {
pub body: Vec<u8>,
src_addr: SocketAddr,
}
impl<'a> futures::stream::Stream for UdpServer<'a> {
type Item = std::io::Result<Request>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let mut buf = [0; 512];
let mut read_buf = tokio::io::ReadBuf::new(&mut buf);
match futures::ready!(self.socket.poll_recv_from(cx, &mut read_buf)) {
Ok(src_addr) => Poll::Ready(Some(Ok(Request {
body: read_buf.filled().to_vec(),
src_addr,
}))),
Err(e) => Poll::Ready(Some(Err(e))),
}
}
}
impl<'a> UdpServer<'a> {
pub fn new(socket: &'a tokio::net::UdpSocket) -> UdpServer {
UdpServer { socket }
}
pub async fn reply(&self, request: &Request, response: &[u8]) -> Result<usize> {
self.socket.send_to(response, request.src_addr).await.map_err(Error::from)
}
}