use super::socket::UdpSocket; use std::io; use std::net::SocketAddr; use futures::{Async, Future, Poll}; /// A future used to write the entire contents of some data to a UDP socket. /// /// This is created by the `UdpSocket::send_dgram` method. #[must_use = "futures do nothing unless polled"] #[derive(Debug)] pub struct SendDgram { /// None means future was completed state: Option> } /// A struct is used to represent the full info of SendDgram. #[derive(Debug)] struct SendDgramInner { /// Tx socket socket: UdpSocket, /// The whole buffer will be sent buffer: T, /// Destination addr addr: SocketAddr, } impl SendDgram { /// Create a new future to send UDP Datagram pub(crate) fn new(socket: UdpSocket, buffer: T, addr: SocketAddr) -> SendDgram { let inner = SendDgramInner { socket: socket, buffer: buffer, addr: addr }; SendDgram { state: Some(inner) } } } fn incomplete_write(reason: &str) -> io::Error { io::Error::new(io::ErrorKind::Other, reason) } impl Future for SendDgram where T: AsRef<[u8]>, { type Item = (UdpSocket, T); type Error = io::Error; fn poll(&mut self) -> Poll<(UdpSocket, T), io::Error> { { let ref mut inner = self.state.as_mut().expect("SendDgram polled after completion"); let n = try_ready!(inner.socket.poll_send_to(inner.buffer.as_ref(), &inner.addr)); if n != inner.buffer.as_ref().len() { return Err(incomplete_write("failed to send entire message \ in datagram")) } } let inner = self.state.take().unwrap(); Ok(Async::Ready((inner.socket, inner.buffer))) } }