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    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    // Server -> Client
149    Welcome {uuid: String},
150    ActiveConnections { users: Vec<ConnectionInfo> },
151    UpdateConnection { connection_info: ConnectionInfo },
152    NotifyDisconnect { uuid: String },
153    // Client -> Server
154    GetConnections {reply_uuid: String},
155    SetConnectionInfo { info: ConnectionInfo },
156    Disconnect,
157    // Client -> Client
158    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    // File Transfer
170    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    // Files
196    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}