From 09f2ac85bf04b732a08250e49084739d1f973a11 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Thu, 15 Nov 2018 16:55:34 +0100 Subject: [PATCH] udp: add `into_parts` to `RecvDgram` (#710) * udp: add `into_parts` to `RecvDgram` If `RecvDgram` can not be driven to completion it may become necessary to get back the `UdpSocket` it contains which is currently not possible. This adds`into_parts` to get the socket as well as the buffer back. Both methods consume `RecvDgram`. Note that after the future has completed, `into_parts` must not be used, or else a panic will happen. --- tokio-udp/src/recv_dgram.rs | 49 +++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tokio-udp/src/recv_dgram.rs b/tokio-udp/src/recv_dgram.rs index 2a9e29606..2f3d5f204 100644 --- a/tokio-udp/src/recv_dgram.rs +++ b/tokio-udp/src/recv_dgram.rs @@ -24,12 +24,61 @@ struct RecvDgramInner { buffer: T } +/// Components of a `RecvDgram` future, returned from `into_parts`. +#[derive(Debug)] +pub struct Parts { + /// The socket + pub socket: UdpSocket, + /// The buffer + pub buffer: T, + + _priv: () +} + impl RecvDgram { /// Create a new future to receive UDP Datagram pub(crate) fn new(socket: UdpSocket, buffer: T) -> RecvDgram { let inner = RecvDgramInner { socket: socket, buffer: buffer }; RecvDgram { state: Some(inner) } } + + /// Consume the `RecvDgram`, returning the socket and buffer. + /// + /// ``` + /// # extern crate tokio_udp; + /// + /// use tokio_udp::UdpSocket; + /// + /// # pub fn main() { + /// + /// let socket = UdpSocket::bind(&([127, 0, 0, 1], 0).into()).unwrap(); + /// let mut buffer = vec![0; 4096]; + /// + /// let future = socket.recv_dgram(buffer); + /// + /// // ... polling `future` ... giving up (e.g. after timeout) + /// + /// let parts = future.into_parts(); + /// + /// let socket = parts.socket; // extract the socket + /// let buffer = parts.buffer; // extract the buffer + /// + /// # } + /// ``` + /// # Panics + /// + /// If called after the future has completed. + pub fn into_parts(mut self) -> Parts { + let state = self.state + .take() + .expect("into_parts called after completion"); + + Parts { + socket: state.socket, + buffer: state.buffer, + _priv: () + } + } } impl Future for RecvDgram