1use std::sync::{Arc, RwLock};
2
3use crate::common::{
4 adress::Adress,
5 packets::{Packets, Search},
6};
7
8mod connection;
9pub mod response;
10pub use connection::*;
11
12use self::response::{RequestStage, Response};
13
14pub struct RelayClient {
15 pub connections: Vec<Arc<RwLock<Connection>>>,
16 pub connection_errors: Vec<ConnectionError>,
17 pub info: ConnectionInfo,
18}
19
20#[derive(Debug)]
21pub enum RelayClientError {
22 ConnectionError(ConnectionError),
23 NoRelays,
24 NoConnections,
25}
26
27pub type SearchResponse = Vec<Response<Box<dyn TConnection>, response::SearchResponse>>;
28
29impl RelayClient {
30 pub fn new(info: ConnectionInfo, relays: Vec<String>) -> Result<Self, RelayClientError> {
31 let mut connection_errors = Vec::new();
32 use RelayClientError::*;
33 if relays.is_empty() {
34 return Err(NoRelays);
35 }
36
37 let mut connections = Vec::new();
38 for relay in relays {
39 match Connection::new(relay, info.clone()) {
40 Ok(conn) => {
41 connections.push(Arc::new(RwLock::new(conn)));
42 }
43 Err(error) => {
44 connection_errors.push(error);
45 }
46 }
47 }
48
49 if connections.is_empty() {
50 println!("Errors: {:?}", connection_errors);
51 return Err(NoConnections);
52 }
53
54 Ok(Self {
55 connections,
56 info,
57 connection_errors,
58 })
59 }
60
61 pub fn step(&mut self) {
62 for conn in self.connections.iter_mut() {
63 conn.step();
64 }
65 }
66
67 pub fn where_is_adress(&self, adress: &Adress) -> Vec<usize> {
68 let mut indexs = Vec::new();
69 for (index, conn) in self.connections.iter().enumerate() {
70 if conn.read().unwrap().adresses.contains(adress) {
71 indexs.push(index);
72 }
73 }
74 indexs
75 }
76
77 pub fn search(&self, search: Search) -> Response<SearchResponse, Vec<Adress>> {
78 let mut responses = Vec::new();
79 for conn in self.connections.iter() {
80 responses.push(conn.search(search.clone()))
81 }
82
83 Response {
84 connection: responses,
85 packets: Packets::Search(search),
86 fn_has: search_fn_has,
87 fn_get: search_fn_get,
88 }
89 }
90
91 pub fn has_new(&self) -> Option<(usize, RequestStage)> {
92 for (index, conn) in self.connections.iter().enumerate() {
93 if let Some(new) = conn.has_new() {
94 return Some((index, new));
95 }
96 }
97
98 None
99 }
100
101 pub fn get(&self, index: usize) -> Option<&dyn TConnection> {
102 if let Some(conn) = self.connections.get(index) {
103 Some(conn)
104 } else {
105 None
106 }
107 }
108}
109
110fn search_fn_has(
113 connections: &Vec<Response<Box<dyn TConnection>, response::SearchResponse>>,
114 _: &Packets,
115) -> bool {
116 let mut count = 0;
117
118 for conn in connections.iter() {
119 count += conn.has() as usize
120 }
121
122 count == connections.len()
123}
124
125fn search_fn_get(
126 connections: Vec<Response<Box<dyn TConnection>, response::SearchResponse>>,
127 _: Packets,
128) -> Vec<Adress> {
129 let mut res = Vec::new();
130
131 for conn in connections {
132 let v = conn.get();
133 for adress in v.adresses {
134 if !res.contains(&adress) {
135 res.push(adress)
136 }
137 }
138 }
139
140 res
141}