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
extern crate zmtp;

pub const EMPTY_FRAME: usize = 1;

macro_rules! method {
    (has_peers) => {
        #[allow(unused)]
        fn has_peers(&self) -> bool { self.peers.len() > 0 }
    };
    (peer_count) => {
        #[allow(unused)]
        fn peer_count(&self) -> usize { self.peers.len() }
    };
    (peer) => {
        #[allow(unused)]
        fn peer(&mut self) -> &mut Peer { &mut self.peers[0] }
    };
    (flush_peer) => {
        #[allow(unused)]
        fn flush_peer(&mut self) -> &mut Self {
            assert_eq!(self.peer().flush().unwrap(), ());
            self
        }
    };
    (add_peer) => {
        #[allow(unused)]
        fn add_peer(&mut self, peer: Peer) { self.peers.push_back(peer) }
    };
    (remove_peer) => {
        #[allow(unused)]
        fn remove_peer(&mut self) -> Peer {
            self.peers.pop_front().expect("No peers to remove")
        }
    };
    (rotate_peers) => {
        #[allow(unused)]
        fn rotate_peers(&mut self) -> &mut Self {
            if self.has_peers() {
                let peer = self.remove_peer();
                self.add_peer(peer);
            }
            self
        }
    };
    (accept) => {
        fn accept(&self, block_policy: &BlockPolicy) -> Option<Peer> {
            let receiver = &self.listener_receiver;
            match *block_policy {
                BlockPolicy::Block => match receiver.recv() {
                    Ok(peer) => Some(peer),
                    _ => None,
                },
                BlockPolicy::DontBlock => match receiver.try_recv() {
                    Ok(peer) => Some(peer),
                    _ => None,
                },
            }
        }
    }
}

macro_rules! methods {
    { $($method:ident)* } => { $(method! { $method })* };
}


#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum BlockPolicy { Block, DontBlock }