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