1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use futures::Async;
use std::net::SocketAddr;

use {ErrorKind, PeerAddr, PollRecv, PollSend, Result, TcpTransport, Transport, UdpTransport};

/// An implementation of [`Transport`] used for communicating with a fixed peer.
///
/// [`Transport`]: ./trait.Transport.html
#[derive(Debug)]
pub struct FixedPeerTransporter<T: Transport, P = <T as Transport>::PeerAddr> {
    exterior_peer: P,
    interior_peer: T::PeerAddr,
    inner: T,
}
impl<T: Transport, P> FixedPeerTransporter<T, P> {
    /// Makes a new `FixedPeerTransporter` instance.
    pub fn new(exterior_peer: P, interior_peer: T::PeerAddr, inner: T) -> Self {
        FixedPeerTransporter {
            exterior_peer,
            interior_peer,
            inner,
        }
    }

    /// Returns a reference to the inner transporter.
    pub fn inner_ref(&self) -> &T {
        &self.inner
    }

    /// Returns a mutable reference to the inner transporter.
    pub fn inner_mut(&mut self) -> &mut T {
        &mut self.inner
    }

    /// Returns a reference to the fixed peer address exposed to users of the transporter.
    pub fn exterior_peer(&self) -> &P {
        &self.exterior_peer
    }

    /// Returns a reference to the fixed peer address used internally in the transporter.
    pub fn interior_peer(&self) -> &T::PeerAddr {
        &self.interior_peer
    }
}
impl<T: Transport, P: PeerAddr> Transport for FixedPeerTransporter<T, P> {
    type PeerAddr = P;
    type SendItem = T::SendItem;
    type RecvItem = T::RecvItem;

    fn start_send(&mut self, peer: Self::PeerAddr, item: Self::SendItem) -> Result<()> {
        track_assert_eq!(
            peer,
            self.exterior_peer,
            ErrorKind::InvalidInput,
            "Unexpected destination peer"
        );
        self.inner.start_send(self.interior_peer.clone(), item)
    }

    fn poll_send(&mut self) -> PollSend {
        self.inner.poll_send()
    }

    fn poll_recv(&mut self) -> PollRecv<(Self::PeerAddr, Self::RecvItem)> {
        loop {
            match self.inner.poll_recv()? {
                Async::NotReady => return Ok(Async::NotReady),
                Async::Ready(None) => return Ok(Async::Ready(None)),
                Async::Ready(Some((peer, item))) => if peer == self.interior_peer {
                    return Ok(Async::Ready(Some((self.exterior_peer.clone(), item))));
                },
            }
        }
    }
}
impl<T: UdpTransport> UdpTransport for FixedPeerTransporter<T, SocketAddr> {
    fn local_addr(&self) -> SocketAddr {
        self.inner.local_addr()
    }
}
impl<T: TcpTransport> From<T> for FixedPeerTransporter<T, SocketAddr> {
    fn from(f: T) -> Self {
        FixedPeerTransporter::new(f.peer_addr(), (), f)
    }
}