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}
136
137#[derive(Serialize, Deserialize, Clone)]
138pub struct FileDefinition {
139 pub path: String,
140 pub file_type: String
141}
142
143#[derive(Serialize, Deserialize, Clone)]
144pub enum CommandType {
145 Welcome {uuid: String},
147 ActiveConnections { users: Vec<ConnectionInfo> },
148 UpdateConnection { connection_info: ConnectionInfo },
149 NotifyDisconnect { uuid: String },
150 GetConnections {reply_uuid: String},
152 SetConnectionInfo { info: ConnectionInfo },
153 Disconnect,
154 Control {
156 message_type: ControlMessage,
157 },
158 RequestCapabilities {
159 reply_uuid: String
160 },
161 ProvideCapabilities {
162 sender_uuid: String,
163 list: Vec<ControlTypes>
164 },
165 Ack,
166 StartFileTransfer {
168 name: String,
169 chunk_count: u64,
170 blob_size: usize,
171 checksum: String,
172 return_uuid: String
173 },
174 FileTransferBlob {
175 name: String,
176 chunk_num: i32,
177 blob: Vec<u8>,
178 return_uuid: String
179 },
180 FileTransferAck {
181 name: String,
182 start: bool,
183 chunk_num: i32,
184 whole: bool,
185 },
186 FileTransferNack {
187 name: String,
188 start: bool,
189 chunk_num: i32,
190 whole: bool
191 },
192 AddFileWatch {
194 return_uuid: String
195 },
196 ProvideFiles {
197 uuid: String,
198 files: Vec<FileDefinition>
199 },
200 UpdateFile {
201 uuid: String,
202 file: FileDefinition,
203 add: bool,
204 }
205}
206
207#[derive(Serialize, Deserialize, Clone)]
208pub enum Destination {
209 Single { destination_uuid: String},
210 Multi { destination_uuids: Vec<String>},
211 Type { destination_type: ConnectionType },
212 All,
213 None
214}
215
216
217impl Destination {
218 pub fn matches_destination(&self, connection_info: &ConnectionInfo) -> bool {
219 match self {
220 Destination::Single { destination_uuid } => { *destination_uuid == connection_info.uuid }
221 Destination::Multi { destination_uuids } => { destination_uuids.contains(&connection_info.uuid) }
222 Destination::Type { destination_type } => { destination_type == connection_info.connection_type }
223 Destination::All => { true }
224 Destination::None => { false }
225 }
226 }
227
228 pub fn matches_uuid(&self, uuid: &String) -> bool {
229 match self {
230 Destination::Single { destination_uuid } => { *destination_uuid == *uuid }
231 Destination::Multi { destination_uuids } => { destination_uuids.contains(uuid) }
232 Destination::Type { .. } => { false }
233 Destination::All => { true }
234 Destination::None => { false }
235 }
236
237 }
238}
239
240#[derive(Serialize, Deserialize, Clone)]
241pub struct WebSocketMessage {
242 pub command: CommandType,
243 pub destination: Destination
244}