1use super::socket::UdpSocket;
2
3use std::io;
4use std::net::SocketAddr;
5
6use futures::{Async, Future, Poll};
7
8#[must_use = "futures do nothing unless polled"]
12#[derive(Debug)]
13pub struct SendDgram<T> {
14 state: Option<SendDgramInner<T>>,
16}
17
18#[derive(Debug)]
20struct SendDgramInner<T> {
21 socket: UdpSocket,
23 buffer: T,
25 addr: SocketAddr,
27}
28
29impl<T> SendDgram<T> {
30 pub(crate) fn new(socket: UdpSocket, buffer: T, addr: SocketAddr) -> SendDgram<T> {
32 let inner = SendDgramInner {
33 socket: socket,
34 buffer: buffer,
35 addr: addr,
36 };
37 SendDgram { state: Some(inner) }
38 }
39}
40
41fn incomplete_write(reason: &str) -> io::Error {
42 io::Error::new(io::ErrorKind::Other, reason)
43}
44
45impl<T> Future for SendDgram<T>
46where
47 T: AsRef<[u8]>,
48{
49 type Item = (UdpSocket, T);
50 type Error = io::Error;
51
52 fn poll(&mut self) -> Poll<(UdpSocket, T), io::Error> {
53 {
54 let ref mut inner = self
55 .state
56 .as_mut()
57 .expect("SendDgram polled after completion");
58 let n = try_ready!(inner
59 .socket
60 .poll_send_to(inner.buffer.as_ref(), &inner.addr));
61 if n != inner.buffer.as_ref().len() {
62 return Err(incomplete_write(
63 "failed to send entire message \
64 in datagram",
65 ));
66 }
67 }
68
69 let inner = self.state.take().unwrap();
70 Ok(Async::Ready((inner.socket, inner.buffer)))
71 }
72}