rekt_lib/datagrams/
connect_requests.rs

1use std::mem::size_of;
2
3use crate::enums::datagram_type::DatagramType;
4use crate::libs::types::{ClientId, Size};
5use crate::libs::utils::{get_bytes_from_slice, get_u16_at_pos, get_u64_at_pos};
6
7// Sent to the broker to start a connection
8#[derive(Debug)]
9#[repr(C)]
10pub struct DtgConnect {
11    pub datagram_type: DatagramType,
12}
13
14impl DtgConnect {
15    pub const fn new() -> DtgConnect {
16        DtgConnect {
17            datagram_type: DatagramType::Connect,
18        }
19    }
20
21    pub fn as_bytes(&self) -> Vec<u8> {
22        [u8::from(self.datagram_type)].into()
23    }
24
25    pub const fn get_default_byte_size() -> usize {
26        1
27    }
28}
29
30impl<'a> TryFrom<&'a [u8]> for DtgConnect {
31    type Error = &'a str;
32
33    fn try_from(buffer: &'a [u8]) -> Result<Self, Self::Error> {
34        if buffer.len() < DtgConnect::get_default_byte_size() {
35            return Err("Payload len is to short for a DtgConnect.");
36        }
37
38        Ok(DtgConnect {
39            datagram_type: DatagramType::from(buffer[0]),
40        })
41    }
42}
43
44//===== Sent to acknowledge the connexion with success
45#[derive(Debug)]
46#[repr(C)]
47pub struct DtgConnectAck {
48    pub datagram_type: DatagramType,
49    pub peer_id: ClientId,
50    pub heartbeat_period: u16,
51}
52
53impl DtgConnectAck {
54    pub const fn new(peer_id: ClientId, heartbeat_period: u16) -> DtgConnectAck {
55        DtgConnectAck {
56            datagram_type: DatagramType::ConnectAck,
57            peer_id,
58            heartbeat_period,
59        }
60    }
61
62    pub fn as_bytes(&self) -> Vec<u8> {
63        let mut bytes: Vec<u8> = Vec::with_capacity(DtgConnectAck::get_default_byte_size());
64        bytes.push(u8::from(self.datagram_type));
65        bytes.extend(self.peer_id.to_le_bytes().into_iter());
66        bytes.extend(self.heartbeat_period.to_le_bytes().into_iter());
67
68        bytes
69    }
70
71    pub fn get_default_byte_size() -> usize {
72        11
73    }
74}
75
76impl<'a> TryFrom<&'a [u8]> for DtgConnectAck {
77    type Error = &'a str;
78
79    fn try_from(buffer: &'a [u8]) -> Result<Self, Self::Error> {
80        if buffer.len() < DtgConnectAck::get_default_byte_size() {
81            return Err("Payload len is to short for a DtgConnectAck.");
82        }
83
84        let peer_id = get_u64_at_pos(buffer, 1)?;
85        let heartbeat_period = get_u16_at_pos(buffer, 9)?;
86
87        Ok(DtgConnectAck {
88            datagram_type: DatagramType::from(buffer[0]),
89            peer_id,
90            heartbeat_period,
91        })
92    }
93}
94
95#[derive(Debug)]
96#[repr(C)]
97pub struct DtgConnectNack {
98    pub datagram_type: DatagramType,
99    pub size: Size,
100    pub payload: Vec<u8>,
101}
102
103impl DtgConnectNack {
104    pub fn new(message: &str) -> DtgConnectNack {
105        let reason: Vec<u8> = message.as_bytes().into();
106        let message_size = reason.len() as Size;
107
108        DtgConnectNack {
109            datagram_type: DatagramType::ConnectNack,
110            size: message_size,
111            payload: reason,
112        }
113    }
114
115    pub fn as_bytes(&self) -> Vec<u8> {
116        let mut bytes: Vec<u8> =
117            Vec::with_capacity(DtgConnectNack::get_default_byte_size() + self.size as usize);
118        bytes.push(u8::from(self.datagram_type));
119        bytes.extend(self.size.to_le_bytes().into_iter());
120        bytes.extend(&mut self.payload.iter());
121
122        bytes
123    }
124
125    pub const fn get_default_byte_size() -> usize {
126        3
127    }
128}
129
130impl<'a> TryFrom<&'a [u8]> for DtgConnectNack {
131    type Error = &'a str;
132
133    fn try_from(buffer: &'a [u8]) -> Result<Self, Self::Error> {
134        if buffer.len() < DtgConnectNack::get_default_byte_size() {
135            return Err("Payload len is to short for a RQ_Connect_Ack_Error.");
136        }
137        let size = get_u16_at_pos(buffer, 1)?;
138
139        Ok(DtgConnectNack {
140            datagram_type: DatagramType::from(buffer[0]),
141            size,
142            payload: get_bytes_from_slice(
143                buffer,
144                DtgConnectNack::get_default_byte_size(),
145                (DtgConnectNack::get_default_byte_size() + size as usize),
146            ),
147        })
148    }
149}