1use crate::peer::Peer;
2use std::error::Error;
3use std::fmt::Debug;
4
5const MSG_TYPE_REQ: u8 = 0x80; const MSG_TYPE_RESP: u8 = 0x00;
7const MASK_MSG_TYPE: u8 = 0x80; #[derive(Debug)]
11pub enum MessageType {
12 Request,
13 Response
14}
15
16#[derive(Debug)]
18pub struct Message {
19 sender: String,
21 message_type: MessageType,
23 view: Option<Vec<Peer>>,
25}
26
27impl Message {
28
29 pub fn new_request(sender: String, view: Option<Vec<Peer>>) -> Message {
31 Self::new(sender, MessageType::Request, view)
32 }
33
34 pub fn new_response(sender: String, view: Option<Vec<Peer>>) -> Message {
36 Self::new(sender, MessageType::Response, view)
37 }
38
39 fn new(sender: String, message_type: MessageType, view: Option<Vec<Peer>>) -> Message {
40 Message{
41 sender,
42 message_type,
43 view
44 }
45 }
46
47 pub fn sender(&self) -> &str {
49 &self.sender
50 }
51
52 pub fn message_type(&self) -> &MessageType{
54 &self.message_type
55 }
56
57 pub fn view(&self) -> &Option<Vec<Peer>> {
59 &self.view
60 }
61
62 pub fn as_bytes(&self) -> Vec<u8> {
64 let mut buffer = vec![];
65 match self.message_type {
67 MessageType::Request => buffer.push(MSG_TYPE_REQ),
68 MessageType::Response => buffer.push(MSG_TYPE_RESP),
69 }
70 buffer.push(self.sender.as_bytes().len() as u8);
72 self.sender.as_bytes().iter().for_each(|byte| buffer.push(*byte));
73 if let Some(peers) = &self.view {
75 buffer.push(peers.len() as u8);
77 peers.iter().map(|p| { p.as_bytes() }).for_each(|mut bytes| {
79 buffer.push(bytes.len() as u8);
81 buffer.append(&mut bytes);
83 });
84 }
85 else {
86 buffer.push(0);
88 }
89 buffer
90 }
91
92 pub fn from_bytes(bytes: &[u8]) -> Result<Message, Box<dyn Error>> {
98
99 if bytes.len() < 4 {
101 Err("invalid message")?
102 }
103
104 let message_type = match bytes[0] & MASK_MSG_TYPE {
106 MSG_TYPE_REQ => MessageType::Request,
107 MSG_TYPE_RESP => MessageType::Response,
108 _ => return Err("invalid message type")?,
109 };
110
111 let sender_size = bytes[1] as usize;
113 if bytes.len() < 3 + sender_size {
115 Err("invalid message")?
116 }
117 let sender = String::from_utf8(bytes[2..2+sender_size].to_vec())?;
118
119 let view_size = bytes[2+sender_size];
121 if bytes.len() < (2 + sender_size + 2 * view_size as usize) {
123 Err("invalid message")?
124 }
125 if view_size > 0 {
126 let mut index = 3+sender_size;
127 let mut peers = vec![];
128 for _ in 0..view_size {
129 let peer_length = bytes[index] as usize;
130 if bytes.len() < index + 1 + peer_length{
132 return Err("invalid message")?;
133 }
134 let parsed_peer = Peer::from_bytes(&bytes[index+1..index+1+peer_length])?;
135 peers.push(parsed_peer);
136 index += peer_length + 1;
137 }
138 Ok(Message {
139 sender,
140 message_type,
141 view: Some(peers)
142 })
143 }
144 else {
145 Ok(Message {
146 sender,
147 message_type,
148 view: None
149 })
150 }
151 }
152}