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