Skip to main content

tunneler_core/message/
header.rs

1use std::convert::TryInto;
2
3use crate::message::MessageType;
4
5/// The Header of a single Message
6#[derive(Debug, PartialEq, Clone)]
7pub struct MessageHeader {
8    /// The ID of the Connection the Message belongs to
9    pub id: u32, // 4 bytes
10    /// The Type of Message
11    pub kind: MessageType, // 1 byte
12    /// The Length of the Data assosicated with this Message
13    pub length: u64, // 8 bytes
14}
15
16impl MessageHeader {
17    /// Creates a new Header with the given Metadata
18    pub fn new(id: u32, kind: MessageType, length: u64) -> MessageHeader {
19        MessageHeader { id, kind, length }
20    }
21
22    /// Deserializes a 13-Byte array into the fitting Message-Header
23    ///
24    /// # Params:
25    /// * `raw_data`: The Byte-Slice that represents a MessageHeader
26    pub fn deserialize(raw_data: &[u8; 13]) -> Option<MessageHeader> {
27        let id_part = &raw_data[0..4];
28        let kind_part = raw_data[4];
29        let length_part = &raw_data[5..13];
30
31        let id = u32::from_le_bytes(id_part.try_into().unwrap());
32        let kind = MessageType::deserialize(kind_part)?;
33        let length = u64::from_le_bytes(length_part.try_into().unwrap());
34
35        Some(MessageHeader { id, kind, length })
36    }
37
38    /// Serializes the Header itself into a 13-Byte array
39    pub fn serialize(&self, target: &mut [u8; 13]) {
40        let id = self.id.to_le_bytes();
41        let length = self.length.to_le_bytes();
42
43        target[0] = id[0];
44        target[1] = id[1];
45        target[2] = id[2];
46        target[3] = id[3];
47
48        target[4] = self.kind.serialize();
49
50        target[5] = length[0];
51        target[6] = length[1];
52        target[7] = length[2];
53        target[8] = length[3];
54        target[9] = length[4];
55        target[10] = length[5];
56        target[11] = length[6];
57        target[12] = length[7];
58    }
59
60    /// Returns the ID of the Connection this message is meant for
61    pub fn get_id(&self) -> u32 {
62        self.id
63    }
64    /// Returns the Type of message
65    pub fn get_kind(&self) -> &MessageType {
66        &self.kind
67    }
68    /// Returns the Length of the data that belongs to this message
69    pub fn get_length(&self) -> u64 {
70        self.length
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn message_header_serialize_connect() {
80        let input = vec![13, 0, 0, 0, 1, 20, 0, 0, 0, 0, 0, 0, 0];
81        let mut output = [0; 13];
82        MessageHeader {
83            id: 13,
84            kind: MessageType::Connect,
85            length: 20,
86        }
87        .serialize(&mut output);
88
89        assert_eq!(&input[0..13], &output[0..13],);
90    }
91
92    #[test]
93    fn message_header_deserialize_connect() {
94        let mut input = [0; 13];
95        input[0] = 13;
96        input[4] = 1;
97        input[5] = 20;
98        assert_eq!(
99            Some(MessageHeader {
100                id: 13,
101                kind: MessageType::Connect,
102                length: 20,
103            }),
104            MessageHeader::deserialize(&input)
105        );
106    }
107
108    #[test]
109    fn serialize_deserialize() {
110        let first = MessageHeader::new(123, MessageType::Data, 123);
111        let mut serialized = [0; 13];
112        first.serialize(&mut serialized);
113        let deserialized = MessageHeader::deserialize(&serialized);
114
115        assert_eq!(true, deserialized.is_some());
116        assert_eq!(first, deserialized.unwrap());
117    }
118}