tokio_udp/recv_dgram.rs
1use super::socket::UdpSocket;
2
3use std::io;
4use std::net::SocketAddr;
5
6use futures::{Async, Future, Poll};
7
8/// A future used to receive a datagram from a UDP socket.
9///
10/// This is created by the `UdpSocket::recv_dgram` method.
11#[must_use = "futures do nothing unless polled"]
12#[derive(Debug)]
13pub struct RecvDgram<T> {
14 /// None means future was completed
15 state: Option<RecvDgramInner<T>>,
16}
17
18/// A struct is used to represent the full info of RecvDgram.
19#[derive(Debug)]
20struct RecvDgramInner<T> {
21 /// Rx socket
22 socket: UdpSocket,
23 /// The received data will be put in the buffer
24 buffer: T,
25}
26
27/// Components of a `RecvDgram` future, returned from `into_parts`.
28#[derive(Debug)]
29pub struct Parts<T> {
30 /// The socket
31 pub socket: UdpSocket,
32 /// The buffer
33 pub buffer: T,
34
35 _priv: (),
36}
37
38impl<T> RecvDgram<T> {
39 /// Create a new future to receive UDP Datagram
40 pub(crate) fn new(socket: UdpSocket, buffer: T) -> RecvDgram<T> {
41 let inner = RecvDgramInner {
42 socket: socket,
43 buffer: buffer,
44 };
45 RecvDgram { state: Some(inner) }
46 }
47
48 /// Consume the `RecvDgram`, returning the socket and buffer.
49 ///
50 /// ```
51 /// # extern crate tokio_udp;
52 ///
53 /// use tokio_udp::UdpSocket;
54 ///
55 /// # pub fn main() {
56 ///
57 /// let socket = UdpSocket::bind(&([127, 0, 0, 1], 0).into()).unwrap();
58 /// let mut buffer = vec![0; 4096];
59 ///
60 /// let future = socket.recv_dgram(buffer);
61 ///
62 /// // ... polling `future` ... giving up (e.g. after timeout)
63 ///
64 /// let parts = future.into_parts();
65 ///
66 /// let socket = parts.socket; // extract the socket
67 /// let buffer = parts.buffer; // extract the buffer
68 ///
69 /// # }
70 /// ```
71 /// # Panics
72 ///
73 /// If called after the future has completed.
74 pub fn into_parts(mut self) -> Parts<T> {
75 let state = self
76 .state
77 .take()
78 .expect("into_parts called after completion");
79
80 Parts {
81 socket: state.socket,
82 buffer: state.buffer,
83 _priv: (),
84 }
85 }
86}
87
88impl<T> Future for RecvDgram<T>
89where
90 T: AsMut<[u8]>,
91{
92 type Item = (UdpSocket, T, usize, SocketAddr);
93 type Error = io::Error;
94
95 fn poll(&mut self) -> Poll<Self::Item, io::Error> {
96 let (n, addr) = {
97 let ref mut inner = self
98 .state
99 .as_mut()
100 .expect("RecvDgram polled after completion");
101
102 try_ready!(inner.socket.poll_recv_from(inner.buffer.as_mut()))
103 };
104
105 let inner = self.state.take().unwrap();
106 Ok(Async::Ready((inner.socket, inner.buffer, n, addr)))
107 }
108}