example_communication_common/
communication.rs1use serde_with::DefaultOnError;
2use serde_with::serde_as;
3use std::cmp::PartialEq;
4use std::fmt;
5use std::fmt::{Display, Formatter};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub enum ConnectionType {
10 Client,
11 Controller
12}
13
14impl PartialEq<ConnectionType> for &ConnectionType {
15 fn eq(&self, other: &ConnectionType) -> bool {
16 match (self,other) {
17 (&ConnectionType::Client, &ConnectionType::Client) => true,
18 (&ConnectionType::Controller, &ConnectionType::Controller) => true,
19 _ => false
20 }
21 }
22}
23
24impl ConnectionType {
25 pub fn as_str(&self) -> &str {
26 match self {
27 ConnectionType::Client => {"Client"}
28 ConnectionType::Controller => {"Controller"}
29 }
30 }
31}
32impl Display for ConnectionType {
33 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
34 write!(f, "{}", self.as_str())
35 }
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct ConnectionInfo {
40 pub uuid: String,
41 pub name: String,
42 pub connection_type: ConnectionType,
43}
44
45impl Display for ConnectionInfo {
46 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
47 write!(f, "(uuid: {} name: {} connection type: {})", self.uuid, self.name, self.connection_type)
48 }
49}
50
51#[derive(Serialize, Deserialize, Clone)]
52pub enum ControlTypes {
53 Default,
54 Message,
55 TransferFile,
56 DeleteFile,
57}
58
59impl Default for ControlTypes {
60 fn default() -> Self { ControlTypes::Default }
61}
62
63pub struct ControlOption {
64 pub display_name: String,
65 pub name: String,
66 pub ui_type: UITypes,
67 pub default_value: String,
68 pub acceptable_option_types: Vec<String>
69}
70
71pub enum UITypes {
72 Text,
73 Checkbox,
74 ComboBox,
75}
76
77pub struct ControlDefinition {
78 pub display_name: String,
79 pub name: String,
80 pub options: Vec<ControlOption>
81}
82
83impl ControlTypes {
84 pub fn as_str(&self) -> String {
85 match self {
86 ControlTypes::Default => {"".to_string()}
87 ControlTypes::Message => {"Message".to_string()}
88 ControlTypes::TransferFile => {"TransferFile".to_string()}
89 ControlTypes::DeleteFile => {"DeleteFile".to_string()}
90 }
91 }
92 pub fn to_definition(&self) -> ControlDefinition {
93 match self {
94 ControlTypes::Default => {
95 ControlDefinition {
96 display_name: "".to_string(),
97 name: "".to_string(),
98 options: vec![],
99 }
100 }
101 ControlTypes::Message => {
102 ControlDefinition {
103 display_name: "Send Message".to_string(),
104 name: self.as_str(),
105 options: vec![ControlOption {
106 display_name: "Text".to_string(),
107 name: "Text".to_string(),
108 ui_type: UITypes::Text,
109 default_value: "".to_string(),
110 acceptable_option_types: vec![],
111 }],
112 }
113 },
114 ControlTypes::TransferFile => {
115 ControlDefinition {
116 display_name: "Transfer File".to_string(),
117 name: self.as_str(),
118 options: vec![ControlOption {
119 display_name: "File Location".to_string(),
120 name: "File".to_string(),
121 ui_type: UITypes::Text,
122 default_value: "".to_string(),
123 acceptable_option_types: vec![],
124 }],
125 }
126 }
127 ControlTypes::DeleteFile => {
128 ControlDefinition {
129 display_name: "Delete File".to_string(),
130 name: self.as_str(),
131 options: vec![ControlOption {
132 display_name: "File To Delete".to_string(),
133 name: "File".to_string(),
134 ui_type: UITypes::ComboBox,
135 default_value: "".to_string(),
136 acceptable_option_types: vec!["ALL".to_string()],
137 }],
138 }
139 }
140 }
141 }
142}
143
144#[derive(Serialize, Deserialize, Clone)]
145pub enum ControlMessage {
146 Default,
147 Message {
148 text: String
149 },
150 TransferFile,
151 DeleteFile {
152 path: String
153 }
154}
155
156impl Default for ControlMessage {
157 fn default() -> Self {ControlMessage::Default}
158}
159
160#[derive(Serialize, Deserialize, Clone)]
161pub struct FileDefinition {
162 pub path: String,
163 pub file_type: String
164}
165
166#[serde_as]
167#[derive(Serialize, Deserialize, Clone)]
168pub enum CommandType {
169 Welcome {uuid: String},
171 ActiveConnections { users: Vec<ConnectionInfo> },
172 UpdateConnection { connection_info: ConnectionInfo },
173 NotifyDisconnect { uuid: String },
174 GetConnections {reply_uuid: String},
176 SetConnectionInfo { info: ConnectionInfo },
177 Disconnect,
178 Control {
180 #[serde_as(deserialize_as = "DefaultOnError")]
181 message_type: ControlMessage,
182 },
183 RequestCapabilities {
184 reply_uuid: String
185 },
186 ProvideCapabilities {
187 sender_uuid: String,
188 #[serde_as(deserialize_as = "DefaultOnError")]
189 list: Vec<ControlTypes>
190 },
191 Ack,
192 StartFileTransfer {
194 name: String,
195 chunk_count: u64,
196 blob_size: usize,
197 checksum: String,
198 return_uuid: String
199 },
200 FileTransferBlob {
201 name: String,
202 chunk_num: i32,
203 blob: Vec<u8>,
204 return_uuid: String
205 },
206 FileTransferAck {
207 name: String,
208 start: bool,
209 chunk_num: i32,
210 whole: bool,
211 },
212 FileTransferNack {
213 name: String,
214 start: bool,
215 chunk_num: i32,
216 whole: bool
217 },
218 AddFileWatch {
220 return_uuid: String
221 },
222 ProvideFiles {
223 uuid: String,
224 files: Vec<FileDefinition>
225 },
226 UpdateFile {
227 uuid: String,
228 file: FileDefinition,
229 add: bool,
230 }
231}
232
233#[derive(Serialize, Deserialize, Clone)]
234pub enum Destination {
235 Single { destination_uuid: String},
236 Multi { destination_uuids: Vec<String>},
237 Type { destination_type: ConnectionType },
238 All,
239 None
240}
241
242
243impl Destination {
244 pub fn matches_destination(&self, connection_info: &ConnectionInfo) -> bool {
245 match self {
246 Destination::Single { destination_uuid } => { *destination_uuid == connection_info.uuid }
247 Destination::Multi { destination_uuids } => { destination_uuids.contains(&connection_info.uuid) }
248 Destination::Type { destination_type } => { destination_type == connection_info.connection_type }
249 Destination::All => { true }
250 Destination::None => { false }
251 }
252 }
253
254 pub fn matches_uuid(&self, uuid: &String) -> bool {
255 match self {
256 Destination::Single { destination_uuid } => { *destination_uuid == *uuid }
257 Destination::Multi { destination_uuids } => { destination_uuids.contains(uuid) }
258 Destination::Type { .. } => { false }
259 Destination::All => { true }
260 Destination::None => { false }
261 }
262
263 }
264}
265
266#[derive(Serialize, Deserialize, Clone)]
267pub struct WebSocketMessage {
268 pub command: CommandType,
269 pub destination: Destination
270}