1use crate::{
33 AdaptivePollingConfig, BackgroundModeConfig, ConnectionLimitsConfig, DhtConfig,
34 GeoRouterConfig, MemoryMonitorConfig, MultipathConfig, NetworkConfig, OfflineQueueConfig,
35 PeerSelectorConfig, PeerStoreConfig, QualityPredictorConfig, QueryBatcherConfig, QuicConfig,
36 ThrottleConfig, TorConfig,
37};
38use std::time::Duration;
39
40#[derive(Debug, Clone)]
42pub struct NetworkPreset {
43 pub network: NetworkConfig,
45 pub quic: QuicConfig,
47 pub dht: DhtConfig,
49 pub peer_store: PeerStoreConfig,
51 pub connection_limits: ConnectionLimitsConfig,
53 pub throttle: Option<ThrottleConfig>,
55 pub adaptive_polling: Option<AdaptivePollingConfig>,
57 pub memory_monitor: Option<MemoryMonitorConfig>,
59 pub offline_queue: Option<OfflineQueueConfig>,
61 pub background_mode: Option<BackgroundModeConfig>,
63 pub query_batcher: Option<QueryBatcherConfig>,
65 pub geo_router: Option<GeoRouterConfig>,
67 pub quality_predictor: Option<QualityPredictorConfig>,
69 pub peer_selector: Option<PeerSelectorConfig>,
71 pub multipath: Option<MultipathConfig>,
73 pub tor: Option<TorConfig>,
75 pub description: String,
77}
78
79impl NetworkPreset {
80 pub fn default_preset() -> Self {
82 Self {
83 network: NetworkConfig::default(),
84 quic: QuicConfig::default(),
85 dht: DhtConfig::default(),
86 peer_store: PeerStoreConfig::default(),
87 connection_limits: ConnectionLimitsConfig::default(),
88 throttle: None,
89 adaptive_polling: None,
90 memory_monitor: None,
91 offline_queue: None,
92 background_mode: None,
93 query_batcher: None,
94 geo_router: None,
95 quality_predictor: None,
96 peer_selector: None,
97 multipath: None,
98 tor: None,
99 description: "Balanced configuration for general use".to_string(),
100 }
101 }
102
103 pub fn low_memory() -> Self {
105 Self {
106 network: NetworkConfig::low_memory(),
107 quic: QuicConfig::mobile(), dht: DhtConfig::default(),
109 peer_store: PeerStoreConfig::low_memory(),
110 connection_limits: ConnectionLimitsConfig {
111 max_connections: 16,
112 max_inbound: 8,
113 max_outbound: 8,
114 reserved_slots: 2,
115 idle_timeout: Duration::from_secs(180),
116 min_score_threshold: 40,
117 },
118 throttle: Some(ThrottleConfig::low_power()),
119 adaptive_polling: Some(AdaptivePollingConfig::low_power()),
120 memory_monitor: Some(MemoryMonitorConfig::low_memory()),
121 offline_queue: None,
122 background_mode: None,
123 query_batcher: Some(QueryBatcherConfig::low_power()),
124 geo_router: None,
125 quality_predictor: None,
126 peer_selector: None,
127 multipath: None,
128 tor: None,
129 description: "Optimized for devices with < 128 MB RAM (RPi Zero, embedded)".to_string(),
130 }
131 }
132
133 pub fn iot() -> Self {
135 Self {
136 network: NetworkConfig::iot(),
137 quic: QuicConfig::mobile(),
138 dht: DhtConfig::default(),
139 peer_store: PeerStoreConfig::iot(),
140 connection_limits: ConnectionLimitsConfig {
141 max_connections: 32,
142 max_inbound: 16,
143 max_outbound: 16,
144 reserved_slots: 4,
145 idle_timeout: Duration::from_secs(240),
146 min_score_threshold: 35,
147 },
148 throttle: Some(ThrottleConfig::iot()),
149 adaptive_polling: Some(AdaptivePollingConfig::iot()),
150 memory_monitor: Some(MemoryMonitorConfig::iot()),
151 offline_queue: Some(OfflineQueueConfig::iot()),
152 background_mode: None,
153 query_batcher: Some(QueryBatcherConfig::low_power()),
154 geo_router: None,
155 quality_predictor: None,
156 peer_selector: None,
157 multipath: None,
158 tor: None,
159 description: "IoT devices with moderate resources (ESP32, RPi 3)".to_string(),
160 }
161 }
162
163 pub fn mobile() -> Self {
165 Self {
166 network: NetworkConfig::mobile(),
167 quic: QuicConfig::mobile(),
168 dht: DhtConfig::default(),
169 peer_store: PeerStoreConfig::mobile(),
170 connection_limits: ConnectionLimitsConfig {
171 max_connections: 64,
172 max_inbound: 32,
173 max_outbound: 32,
174 reserved_slots: 6,
175 idle_timeout: Duration::from_secs(300),
176 min_score_threshold: 30,
177 },
178 throttle: Some(ThrottleConfig::mobile()),
179 adaptive_polling: Some(AdaptivePollingConfig::mobile()),
180 memory_monitor: Some(MemoryMonitorConfig::mobile()),
181 offline_queue: Some(OfflineQueueConfig::mobile()),
182 background_mode: Some(BackgroundModeConfig::mobile()),
183 query_batcher: Some(QueryBatcherConfig::mobile()),
184 geo_router: Some(GeoRouterConfig::low_latency()),
185 quality_predictor: Some(QualityPredictorConfig::low_latency()),
186 peer_selector: Some(PeerSelectorConfig::mobile()),
187 multipath: Some(MultipathConfig::mobile()),
188 tor: None,
189 description: "Mobile devices with battery optimization (iOS, Android)".to_string(),
190 }
191 }
192
193 pub fn high_performance() -> Self {
195 Self {
196 network: NetworkConfig::high_performance(),
197 quic: QuicConfig::high_throughput(),
198 dht: DhtConfig::default(),
199 peer_store: PeerStoreConfig::server(),
200 connection_limits: ConnectionLimitsConfig {
201 max_connections: 1024,
202 max_inbound: 512,
203 max_outbound: 512,
204 reserved_slots: 16,
205 idle_timeout: Duration::from_secs(600),
206 min_score_threshold: 20,
207 },
208 throttle: None, adaptive_polling: Some(AdaptivePollingConfig::high_performance()),
210 memory_monitor: None, offline_queue: None,
212 background_mode: None,
213 query_batcher: Some(QueryBatcherConfig::high_performance()),
214 geo_router: Some(GeoRouterConfig::global()),
215 quality_predictor: Some(QualityPredictorConfig::high_bandwidth()),
216 peer_selector: Some(PeerSelectorConfig::high_bandwidth()),
217 multipath: Some(MultipathConfig::high_bandwidth()),
218 tor: None,
219 description: "Servers and desktops with ample resources (> 2 GB RAM)".to_string(),
220 }
221 }
222
223 pub fn low_latency() -> Self {
225 Self {
226 network: NetworkConfig::default(),
227 quic: QuicConfig::low_latency(),
228 dht: DhtConfig::default(),
229 peer_store: PeerStoreConfig::default(),
230 connection_limits: ConnectionLimitsConfig::default(),
231 throttle: None,
232 adaptive_polling: Some(AdaptivePollingConfig::high_performance()),
233 memory_monitor: None,
234 offline_queue: None,
235 background_mode: None,
236 query_batcher: None, geo_router: Some(GeoRouterConfig::low_latency()),
238 quality_predictor: Some(QualityPredictorConfig::low_latency()),
239 peer_selector: Some(PeerSelectorConfig::low_latency()),
240 multipath: Some(MultipathConfig::low_latency()),
241 tor: None,
242 description: "Optimized for minimal latency (gaming, VoIP, real-time apps)".to_string(),
243 }
244 }
245
246 pub fn high_throughput() -> Self {
248 Self {
249 network: NetworkConfig::high_performance(),
250 quic: QuicConfig::high_throughput(),
251 dht: DhtConfig::default(),
252 peer_store: PeerStoreConfig::server(),
253 connection_limits: ConnectionLimitsConfig {
254 max_connections: 2048,
255 max_inbound: 1024,
256 max_outbound: 1024,
257 reserved_slots: 32,
258 idle_timeout: Duration::from_secs(900),
259 min_score_threshold: 15,
260 },
261 throttle: None,
262 adaptive_polling: Some(AdaptivePollingConfig::high_performance()),
263 memory_monitor: None,
264 offline_queue: None,
265 background_mode: None,
266 query_batcher: None,
267 geo_router: Some(GeoRouterConfig::global()),
268 quality_predictor: Some(QualityPredictorConfig::high_bandwidth()),
269 peer_selector: Some(PeerSelectorConfig::high_bandwidth()),
270 multipath: Some(MultipathConfig::high_bandwidth()),
271 tor: None,
272 description: "Optimized for maximum throughput (CDN, video streaming, bulk transfers)"
273 .to_string(),
274 }
275 }
276
277 pub fn privacy() -> Self {
279 Self {
280 network: NetworkConfig::default(),
281 quic: QuicConfig::default(),
282 dht: DhtConfig::default(),
283 peer_store: PeerStoreConfig::default(),
284 connection_limits: ConnectionLimitsConfig::default(),
285 throttle: None,
286 adaptive_polling: None,
287 memory_monitor: None,
288 offline_queue: None,
289 background_mode: None,
290 query_batcher: None,
291 geo_router: None,
292 quality_predictor: None,
293 peer_selector: None,
294 multipath: None,
295 tor: Some(TorConfig::high_privacy()),
296 description: "Maximum privacy with Tor onion routing and stream isolation".to_string(),
297 }
298 }
299
300 pub fn development() -> Self {
302 Self {
303 network: NetworkConfig::default(),
304 quic: QuicConfig::default(),
305 dht: DhtConfig::default(),
306 peer_store: PeerStoreConfig::default(),
307 connection_limits: ConnectionLimitsConfig {
308 max_connections: 50,
309 max_inbound: 25,
310 max_outbound: 25,
311 reserved_slots: 2,
312 idle_timeout: Duration::from_secs(300),
313 min_score_threshold: 30,
314 },
315 throttle: None,
316 adaptive_polling: None,
317 memory_monitor: None,
318 offline_queue: None,
319 background_mode: None,
320 query_batcher: None,
321 geo_router: None,
322 quality_predictor: None,
323 peer_selector: None,
324 multipath: None,
325 tor: None,
326 description: "Development and testing with moderate limits".to_string(),
327 }
328 }
329
330 pub fn name(&self) -> &str {
332 if self.description.contains("general use") {
333 "Default"
334 } else if self.description.contains("< 128 MB") {
335 "Low Memory"
336 } else if self.description.contains("IoT") {
337 "IoT"
338 } else if self.description.contains("Mobile") {
339 "Mobile"
340 } else if self.description.contains("ample resources") {
341 "High Performance"
342 } else if self.description.contains("minimal latency") {
343 "Low Latency"
344 } else if self.description.contains("maximum throughput") {
345 "High Throughput"
346 } else if self.description.contains("privacy") {
347 "Privacy"
348 } else if self.description.contains("Development") {
349 "Development"
350 } else {
351 "Custom"
352 }
353 }
354
355 pub fn has_throttling(&self) -> bool {
357 self.throttle.is_some()
358 }
359
360 pub fn has_adaptive_polling(&self) -> bool {
362 self.adaptive_polling.is_some()
363 }
364
365 pub fn has_memory_monitoring(&self) -> bool {
367 self.memory_monitor.is_some()
368 }
369
370 pub fn has_offline_queue(&self) -> bool {
372 self.offline_queue.is_some()
373 }
374
375 pub fn has_tor(&self) -> bool {
377 self.tor.is_some()
378 }
379
380 pub fn features_summary(&self) -> Vec<String> {
382 let mut features = Vec::new();
383
384 if self.has_throttling() {
385 features.push("Bandwidth Throttling".to_string());
386 }
387 if self.has_adaptive_polling() {
388 features.push("Adaptive Polling".to_string());
389 }
390 if self.has_memory_monitoring() {
391 features.push("Memory Monitoring".to_string());
392 }
393 if self.has_offline_queue() {
394 features.push("Offline Queue".to_string());
395 }
396 if self.background_mode.is_some() {
397 features.push("Background Mode".to_string());
398 }
399 if self.geo_router.is_some() {
400 features.push("Geographic Routing".to_string());
401 }
402 if self.quality_predictor.is_some() {
403 features.push("Connection Quality Prediction".to_string());
404 }
405 if self.multipath.is_some() {
406 features.push("Multipath QUIC".to_string());
407 }
408 if self.has_tor() {
409 features.push("Tor Privacy".to_string());
410 }
411
412 features
413 }
414}
415
416impl Default for NetworkPreset {
417 fn default() -> Self {
418 Self::default_preset()
419 }
420}
421
422#[cfg(test)]
423mod tests {
424 use super::*;
425
426 #[test]
427 fn test_default_preset() {
428 let preset = NetworkPreset::default_preset();
429 assert_eq!(preset.name(), "Default");
430 assert_eq!(preset.description, "Balanced configuration for general use");
431 assert!(!preset.has_throttling());
432 assert!(!preset.has_memory_monitoring());
433 }
434
435 #[test]
436 fn test_low_memory_preset() {
437 let preset = NetworkPreset::low_memory();
438 assert_eq!(preset.name(), "Low Memory");
439 assert!(preset.has_throttling());
440 assert!(preset.has_adaptive_polling());
441 assert!(preset.has_memory_monitoring());
442 assert!(preset.description.contains("< 128 MB"));
443 }
444
445 #[test]
446 fn test_iot_preset() {
447 let preset = NetworkPreset::iot();
448 assert_eq!(preset.name(), "IoT");
449 assert!(preset.has_throttling());
450 assert!(preset.has_adaptive_polling());
451 assert!(preset.has_memory_monitoring());
452 assert!(preset.has_offline_queue());
453 }
454
455 #[test]
456 fn test_mobile_preset() {
457 let preset = NetworkPreset::mobile();
458 assert_eq!(preset.name(), "Mobile");
459 assert!(preset.has_throttling());
460 assert!(preset.has_adaptive_polling());
461 assert!(preset.has_offline_queue());
462 assert!(preset.background_mode.is_some());
463 assert!(preset.geo_router.is_some());
464 assert!(preset.multipath.is_some());
465 }
466
467 #[test]
468 fn test_high_performance_preset() {
469 let preset = NetworkPreset::high_performance();
470 assert_eq!(preset.name(), "High Performance");
471 assert!(!preset.has_throttling()); assert!(!preset.has_memory_monitoring()); assert!(preset.geo_router.is_some());
474 assert!(preset.multipath.is_some());
475 }
476
477 #[test]
478 fn test_low_latency_preset() {
479 let preset = NetworkPreset::low_latency();
480 assert_eq!(preset.name(), "Low Latency");
481 assert!(!preset.has_throttling());
482 assert!(preset.geo_router.is_some());
483 assert!(preset.quality_predictor.is_some());
484 assert!(preset.multipath.is_some());
485 }
486
487 #[test]
488 fn test_high_throughput_preset() {
489 let preset = NetworkPreset::high_throughput();
490 assert_eq!(preset.name(), "High Throughput");
491 assert!(!preset.has_throttling());
492 assert!(preset.geo_router.is_some());
493 assert!(preset.multipath.is_some());
494 }
495
496 #[test]
497 fn test_privacy_preset() {
498 let preset = NetworkPreset::privacy();
499 assert_eq!(preset.name(), "Privacy");
500 assert!(preset.has_tor());
501 assert!(preset.tor.is_some());
502 }
503
504 #[test]
505 fn test_development_preset() {
506 let preset = NetworkPreset::development();
507 assert_eq!(preset.name(), "Development");
508 assert!(!preset.has_throttling());
509 assert!(!preset.has_tor());
510 }
511
512 #[test]
513 fn test_features_summary() {
514 let preset = NetworkPreset::mobile();
515 let features = preset.features_summary();
516
517 assert!(features.contains(&"Bandwidth Throttling".to_string()));
518 assert!(features.contains(&"Adaptive Polling".to_string()));
519 assert!(features.contains(&"Memory Monitoring".to_string()));
520 assert!(features.contains(&"Offline Queue".to_string()));
521 assert!(features.contains(&"Background Mode".to_string()));
522 assert!(features.contains(&"Geographic Routing".to_string()));
523 assert!(features.contains(&"Multipath QUIC".to_string()));
524 }
525
526 #[test]
527 fn test_all_presets_have_descriptions() {
528 let presets = vec![
529 NetworkPreset::default_preset(),
530 NetworkPreset::low_memory(),
531 NetworkPreset::iot(),
532 NetworkPreset::mobile(),
533 NetworkPreset::high_performance(),
534 NetworkPreset::low_latency(),
535 NetworkPreset::high_throughput(),
536 NetworkPreset::privacy(),
537 NetworkPreset::development(),
538 ];
539
540 for preset in presets {
541 assert!(!preset.description.is_empty());
542 assert!(!preset.name().is_empty());
543 }
544 }
545
546 #[test]
547 fn test_preset_names_unique() {
548 let presets = vec![
549 NetworkPreset::default_preset(),
550 NetworkPreset::low_memory(),
551 NetworkPreset::iot(),
552 NetworkPreset::mobile(),
553 NetworkPreset::high_performance(),
554 NetworkPreset::low_latency(),
555 NetworkPreset::high_throughput(),
556 NetworkPreset::privacy(),
557 NetworkPreset::development(),
558 ];
559
560 let names: Vec<&str> = presets.iter().map(|p| p.name()).collect();
561 let mut unique_names = names.clone();
562 unique_names.sort();
563 unique_names.dedup();
564
565 assert_eq!(
566 names.len(),
567 unique_names.len(),
568 "All preset names should be unique"
569 );
570 }
571}