1use bytes::{Buf, BufMut, Bytes, BytesMut};
4
5use crate::{Error, Result, Version};
6
7#[derive(Debug, Clone, Copy)]
9pub struct Header {
10 pub version: Version,
12 pub msg_type: MessageType,
14 pub length: u16,
16 pub xid: u32,
18}
19
20impl Header {
21 pub const SIZE: usize = 8;
23
24 pub fn encode(&self, buf: &mut BytesMut) {
26 buf.put_u8(self.version.wire_version());
27 buf.put_u8(self.msg_type as u8);
28 buf.put_u16(self.length);
29 buf.put_u32(self.xid);
30 }
31
32 pub fn decode(buf: &mut Bytes) -> Result<Self> {
34 if buf.remaining() < Self::SIZE {
35 return Err(Error::Parse("header too short".into()));
36 }
37
38 let version = Version::try_from(buf.get_u8())?;
39 let msg_type = MessageType::try_from(buf.get_u8())?;
40 let length = buf.get_u16();
41 let xid = buf.get_u32();
42
43 Ok(Self {
44 version,
45 msg_type,
46 length,
47 xid,
48 })
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54#[repr(u8)]
55pub enum MessageType {
56 Hello = 0,
59 Error = 1,
61 EchoRequest = 2,
63 EchoReply = 3,
65 Experimenter = 4,
67
68 FeaturesRequest = 5,
71 FeaturesReply = 6,
73 GetConfigRequest = 7,
75 GetConfigReply = 8,
77 SetConfig = 9,
79
80 PacketIn = 10,
83 FlowRemoved = 11,
85 PortStatus = 12,
87
88 PacketOut = 13,
91 FlowMod = 14,
93 GroupMod = 15,
95 PortMod = 16,
97 TableMod = 17,
99
100 MultipartRequest = 18,
103 MultipartReply = 19,
105
106 BarrierRequest = 20,
109 BarrierReply = 21,
111
112 RoleRequest = 24,
115 RoleReply = 25,
117
118 GetAsyncRequest = 26,
121 GetAsyncReply = 27,
123 SetAsync = 28,
125
126 MeterMod = 29,
129
130 BundleControl = 33,
133 BundleAddMessage = 34,
135}
136
137impl TryFrom<u8> for MessageType {
138 type Error = Error;
139
140 fn try_from(v: u8) -> Result<Self> {
141 match v {
142 0 => Ok(Self::Hello),
143 1 => Ok(Self::Error),
144 2 => Ok(Self::EchoRequest),
145 3 => Ok(Self::EchoReply),
146 4 => Ok(Self::Experimenter),
147 5 => Ok(Self::FeaturesRequest),
148 6 => Ok(Self::FeaturesReply),
149 7 => Ok(Self::GetConfigRequest),
150 8 => Ok(Self::GetConfigReply),
151 9 => Ok(Self::SetConfig),
152 10 => Ok(Self::PacketIn),
153 11 => Ok(Self::FlowRemoved),
154 12 => Ok(Self::PortStatus),
155 13 => Ok(Self::PacketOut),
156 14 => Ok(Self::FlowMod),
157 15 => Ok(Self::GroupMod),
158 16 => Ok(Self::PortMod),
159 17 => Ok(Self::TableMod),
160 18 => Ok(Self::MultipartRequest),
161 19 => Ok(Self::MultipartReply),
162 20 => Ok(Self::BarrierRequest),
163 21 => Ok(Self::BarrierReply),
164 24 => Ok(Self::RoleRequest),
165 25 => Ok(Self::RoleReply),
166 26 => Ok(Self::GetAsyncRequest),
167 27 => Ok(Self::GetAsyncReply),
168 28 => Ok(Self::SetAsync),
169 29 => Ok(Self::MeterMod),
170 33 => Ok(Self::BundleControl),
171 34 => Ok(Self::BundleAddMessage),
172 _ => Err(Error::InvalidMessage(format!("unknown message type: {v}"))),
173 }
174 }
175}
176
177#[derive(Debug)]
179pub struct Message {
180 pub header: Header,
182 pub body: Bytes,
184}
185
186impl Message {
187 pub fn new(version: Version, msg_type: MessageType, xid: u32, body: Bytes) -> Self {
189 let length = (Header::SIZE + body.len()) as u16;
190 Self {
191 header: Header {
192 version,
193 msg_type,
194 length,
195 xid,
196 },
197 body,
198 }
199 }
200
201 pub fn encode(&self) -> BytesMut {
203 let mut buf = BytesMut::with_capacity(self.header.length as usize);
204 self.header.encode(&mut buf);
205 buf.extend_from_slice(&self.body);
206 buf
207 }
208}