1use std::fmt;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum RouterType {
14 LimitOrder,
18
19 V2,
23
24 V3,
28}
29
30impl RouterType {
31 pub const fn all() -> [RouterType; 3] {
33 [RouterType::LimitOrder, RouterType::V2, RouterType::V3]
34 }
35
36 pub const fn as_str(&self) -> &'static str {
38 match self {
39 RouterType::LimitOrder => "LO",
40 RouterType::V2 => "V2",
41 RouterType::V3 => "V3",
42 }
43 }
44}
45
46impl fmt::Display for RouterType {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 write!(f, "{}", self.as_str())
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub struct RouterAvailability {
58 pub limit_order: bool,
60 pub v2: bool,
62 pub v3: bool,
64}
65
66impl RouterAvailability {
67 pub const fn all() -> Self {
69 Self {
70 limit_order: true,
71 v2: true,
72 v3: true,
73 }
74 }
75
76 pub const fn none() -> Self {
78 Self {
79 limit_order: false,
80 v2: false,
81 v3: false,
82 }
83 }
84
85 pub const fn lo_v3_only() -> Self {
87 Self {
88 limit_order: true,
89 v2: false,
90 v3: true,
91 }
92 }
93
94 pub const fn v2_v3_only() -> Self {
96 Self {
97 limit_order: false,
98 v2: true,
99 v3: true,
100 }
101 }
102
103 pub const fn has(&self, router_type: RouterType) -> bool {
105 match router_type {
106 RouterType::LimitOrder => self.limit_order,
107 RouterType::V2 => self.v2,
108 RouterType::V3 => self.v3,
109 }
110 }
111
112 pub fn available_routers(&self) -> Vec<RouterType> {
114 let mut routers = Vec::new();
115 if self.limit_order {
116 routers.push(RouterType::LimitOrder);
117 }
118 if self.v2 {
119 routers.push(RouterType::V2);
120 }
121 if self.v3 {
122 routers.push(RouterType::V3);
123 }
124 routers
125 }
126
127 pub const fn count(&self) -> usize {
129 let mut count = 0;
130 if self.limit_order {
131 count += 1;
132 }
133 if self.v2 {
134 count += 1;
135 }
136 if self.v3 {
137 count += 1;
138 }
139 count
140 }
141
142 pub const fn has_any(&self) -> bool {
144 self.limit_order || self.v2 || self.v3
145 }
146}
147
148impl fmt::Display for RouterAvailability {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 let routers = self.available_routers();
151 if routers.is_empty() {
152 write!(f, "No routers available")
153 } else {
154 write!(
155 f,
156 "{}",
157 routers
158 .iter()
159 .map(|r| r.as_str())
160 .collect::<Vec<_>>()
161 .join(", ")
162 )
163 }
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_router_type_all() {
173 let all = RouterType::all();
174 assert_eq!(all.len(), 3);
175 assert!(all.contains(&RouterType::LimitOrder));
176 assert!(all.contains(&RouterType::V2));
177 assert!(all.contains(&RouterType::V3));
178 }
179
180 #[test]
181 fn test_router_type_display() {
182 assert_eq!(RouterType::LimitOrder.to_string(), "LO");
183 assert_eq!(RouterType::V2.to_string(), "V2");
184 assert_eq!(RouterType::V3.to_string(), "V3");
185 }
186
187 #[test]
188 fn test_router_availability_all() {
189 let avail = RouterAvailability::all();
190 assert!(avail.limit_order);
191 assert!(avail.v2);
192 assert!(avail.v3);
193 assert_eq!(avail.count(), 3);
194 }
195
196 #[test]
197 fn test_router_availability_none() {
198 let avail = RouterAvailability::none();
199 assert!(!avail.limit_order);
200 assert!(!avail.v2);
201 assert!(!avail.v3);
202 assert_eq!(avail.count(), 0);
203 assert!(!avail.has_any());
204 }
205
206 #[test]
207 fn test_router_availability_lo_v3_only() {
208 let avail = RouterAvailability::lo_v3_only();
209 assert!(avail.limit_order);
210 assert!(!avail.v2);
211 assert!(avail.v3);
212 assert_eq!(avail.count(), 2);
213 assert!(avail.has(RouterType::LimitOrder));
214 assert!(!avail.has(RouterType::V2));
215 assert!(avail.has(RouterType::V3));
216 }
217
218 #[test]
219 fn test_router_availability_v2_v3_only() {
220 let avail = RouterAvailability::v2_v3_only();
221 assert!(!avail.limit_order);
222 assert!(avail.v2);
223 assert!(avail.v3);
224 assert_eq!(avail.count(), 2);
225 }
226
227 #[test]
228 fn test_available_routers() {
229 let avail = RouterAvailability::all();
230 let routers = avail.available_routers();
231 assert_eq!(routers.len(), 3);
232
233 let avail = RouterAvailability::lo_v3_only();
234 let routers = avail.available_routers();
235 assert_eq!(routers.len(), 2);
236 assert!(routers.contains(&RouterType::LimitOrder));
237 assert!(routers.contains(&RouterType::V3));
238 }
239
240 #[test]
241 fn test_display() {
242 let avail = RouterAvailability::all();
243 assert_eq!(avail.to_string(), "LO, V2, V3");
244
245 let avail = RouterAvailability::lo_v3_only();
246 assert_eq!(avail.to_string(), "LO, V3");
247
248 let avail = RouterAvailability::none();
249 assert_eq!(avail.to_string(), "No routers available");
250 }
251}