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