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 Message,
54 TransferFile,
55 DeleteFile,
56}
57
58pub struct ControlOption {
59 pub display_name: String,
60 pub name: String,
61 pub ui_type: UITypes,
62 pub default_value: String,
63 pub acceptable_option_types: Vec<String>
64}
65
66pub enum UITypes {
67 Text,
68 Checkbox,
69 ComboBox,
70}
71
72pub struct ControlDefinition {
73 pub display_name: String,
74 pub name: String,
75 pub options: Vec<ControlOption>
76}
77
78impl ControlTypes {
79 pub fn as_str(&self) -> String {
80 match self {
81 ControlTypes::Message => {"Message".to_string()}
82 ControlTypes::TransferFile => {"TransferFile".to_string()}
83 ControlTypes::DeleteFile => {"DeleteFile".to_string()}
84 }
85 }
86 pub fn to_definition(&self) -> ControlDefinition {
87 match self {
88 ControlTypes::Message => {
89 ControlDefinition {
90 display_name: "Send Message".to_string(),
91 name: self.as_str(),
92 options: vec![ControlOption {
93 display_name: "Text".to_string(),
94 name: "Text".to_string(),
95 ui_type: UITypes::Text,
96 default_value: "".to_string(),
97 acceptable_option_types: vec![],
98 }],
99 }
100 },
101 ControlTypes::TransferFile => {
102 ControlDefinition {
103 display_name: "Transfer File".to_string(),
104 name: self.as_str(),
105 options: vec![ControlOption {
106 display_name: "File Location".to_string(),
107 name: "File".to_string(),
108 ui_type: UITypes::Text,
109 default_value: "".to_string(),
110 acceptable_option_types: vec![],
111 }],
112 }
113 }
114 ControlTypes::DeleteFile => {
115 ControlDefinition {
116 display_name: "Delete File".to_string(),
117 name: self.as_str(),
118 options: vec![ControlOption {
119 display_name: "File To Delete".to_string(),
120 name: "File".to_string(),
121 ui_type: UITypes::ComboBox,
122 default_value: "".to_string(),
123 acceptable_option_types: vec!["ALL".to_string()],
124 }],
125 }
126 }
127 }
128 }
129}
130
131#[derive(Serialize, Deserialize, Clone)]
132pub enum ControlMessage {
133 Default,
134 Message {
135 text: String
136 },
137 TransferFile,
138 DeleteFile {
139 path: String
140 }
141}
142
143impl Default for ControlMessage {
144 fn default() -> Self {ControlMessage::Default}
145}
146
147#[derive(Serialize, Deserialize, Clone)]
148pub struct FileDefinition {
149 pub path: String,
150 pub file_type: String
151}
152
153#[serde_as]
154#[derive(Serialize, Deserialize, Clone)]
155pub enum CommandType {
156 Welcome {uuid: String},
158 ActiveConnections { users: Vec<ConnectionInfo> },
159 UpdateConnection { connection_info: ConnectionInfo },
160 NotifyDisconnect { uuid: String },
161 GetConnections {reply_uuid: String},
163 SetConnectionInfo { info: ConnectionInfo },
164 Disconnect,
165 Control {
167 #[serde_as(deserialize_as = "DefaultOnError")]
168 message_type: ControlMessage,
169 },
170 RequestCapabilities {
171 reply_uuid: String
172 },
173 ProvideCapabilities {
174 sender_uuid: String,
175 list: Vec<ControlTypes>
176 },
177 Ack,
178 StartFileTransfer {
180 name: String,
181 chunk_count: u64,
182 blob_size: usize,
183 checksum: String,
184 return_uuid: String
185 },
186 FileTransferBlob {
187 name: String,
188 chunk_num: i32,
189 blob: Vec<u8>,
190 return_uuid: String
191 },
192 FileTransferAck {
193 name: String,
194 start: bool,
195 chunk_num: i32,
196 whole: bool,
197 },
198 FileTransferNack {
199 name: String,
200 start: bool,
201 chunk_num: i32,
202 whole: bool
203 },
204 AddFileWatch {
206 return_uuid: String
207 },
208 ProvideFiles {
209 uuid: String,
210 files: Vec<FileDefinition>
211 },
212 UpdateFile {
213 uuid: String,
214 file: FileDefinition,
215 add: bool,
216 }
217}
218
219#[derive(Serialize, Deserialize, Clone)]
220pub enum Destination {
221 Single { destination_uuid: String},
222 Multi { destination_uuids: Vec<String>},
223 Type { destination_type: ConnectionType },
224 All,
225 None
226}
227
228
229impl Destination {
230 pub fn matches_destination(&self, connection_info: &ConnectionInfo) -> bool {
231 match self {
232 Destination::Single { destination_uuid } => { *destination_uuid == connection_info.uuid }
233 Destination::Multi { destination_uuids } => { destination_uuids.contains(&connection_info.uuid) }
234 Destination::Type { destination_type } => { destination_type == connection_info.connection_type }
235 Destination::All => { true }
236 Destination::None => { false }
237 }
238 }
239
240 pub fn matches_uuid(&self, uuid: &String) -> bool {
241 match self {
242 Destination::Single { destination_uuid } => { *destination_uuid == *uuid }
243 Destination::Multi { destination_uuids } => { destination_uuids.contains(uuid) }
244 Destination::Type { .. } => { false }
245 Destination::All => { true }
246 Destination::None => { false }
247 }
248
249 }
250}
251
252#[derive(Serialize, Deserialize, Clone)]
253pub struct WebSocketMessage {
254 pub command: CommandType,
255 pub destination: Destination
256}