1use std::{net::SocketAddr, mem, ops::AddAssign, fmt};
5use smallvec::SmallVec;
6
7#[derive(Default, Debug)]
10pub struct Request {
11 source: Option<ConnectionSource>,
12 blacklist: SmallVec<[SocketAddr; 4]>,
13 connect: SmallVec<[SocketAddr; 8]>,
14}
15
16impl Request {
17 pub fn set_source(self, source: ConnectionSource) -> Self {
18 let mut s = self;
19 s.source = Some(source);
20 s
21 }
22
23 pub fn add_to_blacklist<A>(self, addr: A) -> Self
24 where
25 A: Into<SocketAddr>,
26 {
27 let mut s = self;
28 s.blacklist.push(addr.into());
29 s
30 }
31
32 pub fn add_batch_to_blacklist<I>(self, batch: I) -> Self
33 where
34 I: IntoIterator<Item = SocketAddr>,
35 {
36 let mut s = self;
37 s.blacklist.extend(batch);
38 s
39 }
40
41 pub fn add_connect<A>(self, addr: A) -> Self
42 where
43 A: Into<SocketAddr>,
44 {
45 let mut s = self;
46 s.connect.push(addr.into());
47 s
48 }
49
50 pub fn add_batch_connect<I>(self, batch: I) -> Self
51 where
52 I: IntoIterator<Item = SocketAddr>,
53 {
54 let mut s = self;
55 s.connect.extend(batch);
56 s
57 }
58
59 pub fn is_empty(&self) -> bool {
60 self.source.is_none() && self.blacklist.is_empty() && self.connect.is_empty()
61 }
62
63 pub fn take_new_source(&mut self) -> Option<ConnectionSource> {
64 self.source.take()
65 }
66
67 pub fn take_blacklist(&mut self) -> impl Iterator<Item = SocketAddr> {
68 mem::take(&mut self.blacklist).into_iter()
69 }
70
71 pub fn take_connects(&mut self) -> impl Iterator<Item = SocketAddr> {
72 mem::take(&mut self.connect).into_iter()
73 }
74}
75
76impl AddAssign<Request> for Request {
77 fn add_assign(&mut self, rhs: Request) {
78 let Request {
79 source,
80 mut blacklist,
81 mut connect,
82 } = rhs;
83 #[allow(clippy::suspicious_op_assign_impl)]
84 if self.source.is_none() && source.is_some() {
85 self.source = source;
86 }
87 self.blacklist.append(&mut blacklist);
88 self.connect.append(&mut connect);
89 }
90}
91
92#[derive(Debug, Clone, Copy)]
94pub enum ConnectionSource {
95 None,
97 Port(u16),
99}
100
101impl fmt::Display for ConnectionSource {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 match self {
104 ConnectionSource::None => write!(f, "none"),
105 ConnectionSource::Port(port) => write!(f, "port({})", port),
106 }
107 }
108}