Merge pull request #271 from cramertj/simplify-udp

Simplify UdpSocket futures
This commit is contained in:
Alex Crichton
2017-10-27 22:36:14 -04:00
committed by GitHub
+20 -62
View File
@@ -1,5 +1,4 @@
use std::io; use std::io;
use std::mem;
use std::net::{self, SocketAddr, Ipv4Addr, Ipv6Addr}; use std::net::{self, SocketAddr, Ipv4Addr, Ipv6Addr};
use std::fmt; use std::fmt;
@@ -172,13 +171,7 @@ impl UdpSocket {
pub fn send_dgram<T>(self, buf: T, addr: SocketAddr) -> SendDgram<T> pub fn send_dgram<T>(self, buf: T, addr: SocketAddr) -> SendDgram<T>
where T: AsRef<[u8]>, where T: AsRef<[u8]>,
{ {
SendDgram { SendDgram(Some((self, buf, addr)))
state: SendState::Writing {
sock: self,
addr: addr,
buf: buf,
},
}
} }
/// Receives data from the socket. On success, returns the number of bytes /// Receives data from the socket. On success, returns the number of bytes
@@ -215,12 +208,7 @@ impl UdpSocket {
pub fn recv_dgram<T>(self, buf: T) -> RecvDgram<T> pub fn recv_dgram<T>(self, buf: T) -> RecvDgram<T>
where T: AsMut<[u8]>, where T: AsMut<[u8]>,
{ {
RecvDgram { RecvDgram(Some((self, buf)))
state: RecvState::Reading {
sock: self,
buf: buf,
},
}
} }
/// Gets the value of the `SO_BROADCAST` option for this socket. /// Gets the value of the `SO_BROADCAST` option for this socket.
@@ -395,18 +383,7 @@ impl fmt::Debug for UdpSocket {
/// ///
/// This is created by the `UdpSocket::send_dgram` method. /// This is created by the `UdpSocket::send_dgram` method.
#[must_use = "futures do nothing unless polled"] #[must_use = "futures do nothing unless polled"]
pub struct SendDgram<T> { pub struct SendDgram<T>(Option<(UdpSocket, T, SocketAddr)>);
state: SendState<T>,
}
enum SendState<T> {
Writing {
sock: UdpSocket,
buf: T,
addr: SocketAddr,
},
Empty,
}
fn incomplete_write(reason: &str) -> io::Error { fn incomplete_write(reason: &str) -> io::Error {
io::Error::new(io::ErrorKind::Other, reason) io::Error::new(io::ErrorKind::Other, reason)
@@ -419,23 +396,18 @@ impl<T> Future for SendDgram<T>
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<(UdpSocket, T), io::Error> { fn poll(&mut self) -> Poll<(UdpSocket, T), io::Error> {
match self.state { {
SendState::Writing { ref sock, ref buf, ref addr } => { let (ref sock, ref buf, ref addr) =
let n = try_nb!(sock.send_to(buf.as_ref(), addr)); *self.0.as_ref().expect("SendDgram polled after completion");
if n != buf.as_ref().len() { let n = try_nb!(sock.send_to(buf.as_ref(), addr));
return Err(incomplete_write("failed to send entire message \ if n != buf.as_ref().len() {
in datagram")) return Err(incomplete_write("failed to send entire message \
} in datagram"))
} }
SendState::Empty => panic!("poll a SendDgram after it's done"),
} }
match mem::replace(&mut self.state, SendState::Empty) { let (sock, buf, _addr) = self.0.take().unwrap();
SendState::Writing { sock, buf, addr: _ } => { Ok(Async::Ready((sock, buf)))
Ok(Async::Ready((sock, buf)))
}
SendState::Empty => panic!(),
}
} }
} }
@@ -443,17 +415,7 @@ impl<T> Future for SendDgram<T>
/// ///
/// This is created by the `UdpSocket::recv_dgram` method. /// This is created by the `UdpSocket::recv_dgram` method.
#[must_use = "futures do nothing unless polled"] #[must_use = "futures do nothing unless polled"]
pub struct RecvDgram<T> { pub struct RecvDgram<T>(Option<(UdpSocket, T)>);
state: RecvState<T>,
}
enum RecvState<T> {
Reading {
sock: UdpSocket,
buf: T,
},
Empty,
}
impl<T> Future for RecvDgram<T> impl<T> Future for RecvDgram<T>
where T: AsMut<[u8]>, where T: AsMut<[u8]>,
@@ -462,19 +424,15 @@ impl<T> Future for RecvDgram<T>
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, io::Error> { fn poll(&mut self) -> Poll<Self::Item, io::Error> {
let (n, addr) = match self.state { let (n, addr) = {
RecvState::Reading { ref sock, ref mut buf } => { let (ref socket, ref mut buf) =
try_nb!(sock.recv_from(buf.as_mut())) *self.0.as_mut().expect("RecvDgram polled after completion");
}
RecvState::Empty => panic!("poll a RecvDgram after it's done"), try_nb!(socket.recv_from(buf.as_mut()))
}; };
match mem::replace(&mut self.state, RecvState::Empty) { let (socket, buf) = self.0.take().unwrap();
RecvState::Reading { sock, buf } => { Ok(Async::Ready((socket, buf, n, addr)))
Ok(Async::Ready((sock, buf, n, addr)))
}
RecvState::Empty => panic!(),
}
} }
} }