1use bytes::{Buf, BufMut, Bytes, BytesMut};
6
7pub const STREAM_HEADER_SIZE: usize = 8;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
12pub struct StreamFlags(u8);
13
14impl StreamFlags {
15 const KNOWN_MASK: u8 = Self::FIN.0 | Self::RST.0 | Self::ACK.0 | Self::SYN.0;
16
17 pub const NONE: StreamFlags = StreamFlags(0);
19 pub const FIN: StreamFlags = StreamFlags(1);
21 pub const RST: StreamFlags = StreamFlags(2);
23 pub const ACK: StreamFlags = StreamFlags(4);
25 pub const SYN: StreamFlags = StreamFlags(8);
27
28 pub fn from_byte(b: u8) -> Self {
30 StreamFlags(b)
31 }
32
33 pub fn as_byte(self) -> u8 {
35 self.0
36 }
37
38 pub fn is_empty(self) -> bool {
40 self.0 == 0
41 }
42
43 pub fn has_unknown_bits(self) -> bool {
45 self.0 & !Self::KNOWN_MASK != 0
46 }
47
48 pub fn is_fin(self) -> bool {
50 self.0 & Self::FIN.0 != 0
51 }
52
53 pub fn is_rst(self) -> bool {
55 self.0 & Self::RST.0 != 0
56 }
57
58 pub fn is_ack(self) -> bool {
60 self.0 & Self::ACK.0 != 0
61 }
62
63 pub fn is_syn(self) -> bool {
65 self.0 & Self::SYN.0 != 0
66 }
67
68 pub fn with(self, other: StreamFlags) -> StreamFlags {
70 StreamFlags(self.0 | other.0)
71 }
72}
73
74impl std::ops::BitOr for StreamFlags {
75 type Output = Self;
76
77 fn bitor(self, rhs: Self) -> Self::Output {
78 StreamFlags(self.0 | rhs.0)
79 }
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
90pub struct StreamHeader {
91 pub stream_id: u16,
93 pub flags: StreamFlags,
95 pub reserved: u8,
97 pub length: u32,
99}
100
101impl StreamHeader {
102 pub const CONTROL_STREAM: u16 = 0;
104
105 pub const MAX_STREAM_ID: u16 = 65535;
107
108 pub fn new(stream_id: u16, flags: StreamFlags, length: u32) -> Self {
110 Self {
111 stream_id,
112 flags,
113 reserved: 0,
114 length,
115 }
116 }
117
118 pub fn data(stream_id: u16, length: u32) -> Self {
120 Self::new(stream_id, StreamFlags::NONE, length)
121 }
122
123 pub fn syn(stream_id: u16) -> Self {
125 Self::new(stream_id, StreamFlags::SYN, 0)
126 }
127
128 pub fn fin(stream_id: u16) -> Self {
130 Self::new(stream_id, StreamFlags::FIN, 0)
131 }
132
133 pub fn rst(stream_id: u16) -> Self {
135 Self::new(stream_id, StreamFlags::RST, 0)
136 }
137
138 pub fn ack(stream_id: u16) -> Self {
140 Self::new(stream_id, StreamFlags::ACK, 0)
141 }
142
143 pub fn is_control(&self) -> bool {
145 self.stream_id == Self::CONTROL_STREAM
146 }
147
148 pub fn encode(&self, dst: &mut BytesMut) {
150 dst.put_u16(self.stream_id);
151 dst.put_u8(self.flags.as_byte());
152 dst.put_u8(self.reserved);
153 dst.put_u32(self.length);
154 }
155
156 pub fn to_bytes(&self) -> Bytes {
158 let mut buf = BytesMut::with_capacity(STREAM_HEADER_SIZE);
159 self.encode(&mut buf);
160 buf.freeze()
161 }
162
163 pub fn decode(src: &[u8]) -> Option<Self> {
165 if src.len() < STREAM_HEADER_SIZE {
166 return None;
167 }
168
169 Some(Self {
170 stream_id: u16::from_be_bytes([src[0], src[1]]),
171 flags: StreamFlags::from_byte(src[2]),
172 reserved: src[3],
173 length: u32::from_be_bytes([src[4], src[5], src[6], src[7]]),
174 })
175 }
176
177 pub fn decode_from(src: &mut BytesMut) -> Option<Self> {
179 if src.len() < STREAM_HEADER_SIZE {
180 return None;
181 }
182
183 let header = Self::decode(src)?;
184 src.advance(STREAM_HEADER_SIZE);
185 Some(header)
186 }
187
188 pub fn frame_size(&self) -> usize {
190 STREAM_HEADER_SIZE + self.length as usize
191 }
192}
193
194#[cfg(test)]
195mod tests {
196 use super::*;
197
198 #[test]
199 fn test_stream_flags() {
200 let flags = StreamFlags::FIN | StreamFlags::ACK;
201 assert!(flags.is_fin());
202 assert!(flags.is_ack());
203 assert!(!flags.is_rst());
204 assert!(!flags.is_syn());
205 }
206
207 #[test]
208 fn test_stream_header_encode_decode() {
209 let header = StreamHeader::new(42, StreamFlags::FIN, 1234);
210 let mut buf = BytesMut::new();
211 header.encode(&mut buf);
212
213 assert_eq!(buf.len(), STREAM_HEADER_SIZE);
214
215 let decoded = StreamHeader::decode(&buf).unwrap();
216 assert_eq!(decoded.stream_id, 42);
217 assert!(decoded.flags.is_fin());
218 assert_eq!(decoded.length, 1234);
219 }
220
221 #[test]
222 fn test_stream_header_helpers() {
223 let syn = StreamHeader::syn(1);
224 assert!(syn.flags.is_syn());
225 assert_eq!(syn.stream_id, 1);
226
227 let fin = StreamHeader::fin(2);
228 assert!(fin.flags.is_fin());
229 assert_eq!(fin.stream_id, 2);
230
231 let rst = StreamHeader::rst(3);
232 assert!(rst.flags.is_rst());
233 assert_eq!(rst.stream_id, 3);
234 }
235
236 #[test]
237 fn test_control_stream() {
238 let header = StreamHeader::data(StreamHeader::CONTROL_STREAM, 100);
239 assert!(header.is_control());
240
241 let header = StreamHeader::data(1, 100);
242 assert!(!header.is_control());
243 }
244
245 #[test]
246 fn test_frame_size() {
247 let header = StreamHeader::data(1, 100);
248 assert_eq!(header.frame_size(), STREAM_HEADER_SIZE + 100);
249 }
250}