tokio_uds/
recv_dgram.rs

1use UnixDatagram;
2
3use futures::{Async, Future, Poll};
4
5use std::io;
6use std::mem;
7
8/// A future for receiving datagrams from a Unix datagram socket.
9///
10/// An example that uses UDP sockets but is still applicable can be found at
11/// https://gist.github.com/dermesser/e331094c2ab28fc7f6ba8a16183fe4d5.
12#[derive(Debug)]
13pub struct RecvDgram<T> {
14    st: State<T>,
15}
16
17/// A future similar to RecvDgram, but without allocating and returning the peer's address.
18///
19/// This can be used if the peer's address is of no interest, so the allocation overhead can be
20/// avoided.
21#[derive(Debug)]
22enum State<T> {
23    Receiving { sock: UnixDatagram, buf: T },
24    Empty,
25}
26
27impl<T> RecvDgram<T>
28where
29    T: AsMut<[u8]>,
30{
31    pub(crate) fn new(sock: UnixDatagram, buf: T) -> RecvDgram<T> {
32        RecvDgram {
33            st: State::Receiving { sock, buf },
34        }
35    }
36}
37
38impl<T> Future for RecvDgram<T>
39where
40    T: AsMut<[u8]>,
41{
42    /// RecvDgram yields a tuple of the underlying socket, the receive buffer, how many bytes were
43    /// received, and the address (path) of the peer sending the datagram. If the buffer is too small, the
44    /// datagram is truncated.
45    type Item = (UnixDatagram, T, usize, String);
46    /// This future yields io::Error if an error occurred.
47    type Error = io::Error;
48
49    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
50        let received;
51        let peer;
52
53        if let State::Receiving {
54            ref mut sock,
55            ref mut buf,
56        } = self.st
57        {
58            let (n, p) = try_ready!(sock.poll_recv_from(buf.as_mut()));
59            received = n;
60
61            peer = p.as_pathname().map_or(String::new(), |p| {
62                p.to_str().map_or(String::new(), |s| s.to_string())
63            });
64        } else {
65            panic!()
66        }
67
68        if let State::Receiving { sock, buf } = mem::replace(&mut self.st, State::Empty) {
69            Ok(Async::Ready((sock, buf, received, peer)))
70        } else {
71            panic!()
72        }
73    }
74}