Skip to main content

example_communication_common/
communication.rs

1use 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    // Server -> Client
146    Welcome {uuid: String},
147    ActiveConnections { users: Vec<ConnectionInfo> },
148    UpdateConnection { connection_info: ConnectionInfo },
149    NotifyDisconnect { uuid: String },
150    // Client -> Server
151    GetConnections {reply_uuid: String},
152    SetConnectionInfo { info: ConnectionInfo },
153    Disconnect,
154    // Client -> Client
155    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    // File Transfer
167    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    // Files
193    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}