wasmrs_frames/frames/
header.rs1use bytes::{BufMut, Bytes, BytesMut};
2
3use super::{FrameFlags, FrameHeader, FrameType};
4use crate::util::from_u16_bytes;
5use crate::Frame;
6
7impl FrameHeader {
8 pub(crate) fn new(stream_id: u32, frame_type: FrameType, frame_flags: u16) -> Self {
9 let mut header = BytesMut::with_capacity(Frame::LEN_HEADER);
10 let frame_type: u32 = frame_type.into();
11 let frame_type: u16 = frame_type.try_into().unwrap();
12 let frame_type = (frame_type << 10) | frame_flags;
13
14 header.put(stream_id.to_be_bytes().as_slice());
15 header.put(frame_type.to_be_bytes().as_slice());
16
17 Self {
18 header: header.freeze(),
19 }
20 }
21
22 pub(crate) fn from_bytes(header: Bytes) -> Self {
23 Self { header }
24 }
25
26 #[cfg(test)]
27 fn as_bytes(&self) -> &[u8] {
28 &self.header
29 }
30
31 pub(crate) fn encode(self) -> Bytes {
32 self.header
33 }
34
35 pub(crate) fn stream_id(&self) -> u32 {
36 let bytes: [u8; 4] = [self.header[0] & 0x7f, self.header[1], self.header[2], self.header[3]];
37 u32::from_be_bytes(bytes)
38 }
39
40 fn n(&self) -> u16 {
41 from_u16_bytes(&self.header.slice(4..Frame::LEN_HEADER))
42 }
43
44 pub(crate) fn frame_type(&self) -> FrameType {
45 let id: u8 = self.header[4] >> 2;
46 id.try_into().unwrap()
47 }
48
49 pub(crate) fn check(&self, flag: FrameFlags) -> bool {
50 self.n() & flag == flag
51 }
52
53 pub(crate) fn has_metadata(&self) -> bool {
54 self.check(Frame::FLAG_METADATA)
55 }
56
57 pub(crate) fn has_follows(&self) -> bool {
58 self.check(Frame::FLAG_FOLLOW)
59 }
60
61 pub(crate) fn has_next(&self) -> bool {
62 self.check(Frame::FLAG_NEXT)
63 }
64
65 pub(crate) fn has_complete(&self) -> bool {
66 self.check(Frame::FLAG_COMPLETE)
67 }
68
69 pub(crate) fn has_ignore(&self) -> bool {
70 self.check(Frame::FLAG_IGNORE)
71 }
72}
73
74impl std::fmt::Display for FrameHeader {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 let mut flags = Vec::new();
77 if self.has_next() {
78 flags.push("N");
79 }
80 if self.has_complete() {
81 flags.push("CL");
82 }
83 if self.has_follows() {
84 flags.push("FRS");
85 }
86 if self.has_metadata() {
87 flags.push("M");
88 }
89 if self.has_ignore() {
90 flags.push("I");
91 }
92
93 let t = self.frame_type();
94 f.write_str("FrameHeader{{id=")?;
95 self.stream_id().fmt(f)?;
96 f.write_str(",type=")?;
97 t.fmt(f)?;
98 f.write_str(",flag=")?;
99 flags.join("|").fmt(f)?;
100 f.write_str("}}")
101 }
102}
103
104#[cfg(test)]
105mod test {
106 use super::*;
107 use anyhow::Result;
108
109 fn print_binary(v: &[u8]) {
110 let mut bytes = Vec::new();
111 for byte in v {
112 bytes.push(format!("{:08b}", byte));
113 }
114 println!("[{}]", bytes.join(" "));
115 }
116 use crate::Frame;
117
118 #[test]
119 fn test_new_header() -> Result<()> {
120 let header = FrameHeader::new(2147483647, FrameType::Payload, Frame::FLAG_COMPLETE);
121 println!("Bytes: {:?}", header.as_bytes());
122 println!("Frame type: {}", header.frame_type());
123 print_binary(header.as_bytes());
124 println!("Header: {}", header);
125 assert_eq!(header.stream_id(), 2147483647);
126 assert_eq!(header.frame_type() as u32, FrameType::Payload.into());
127 assert!(header.has_complete());
128 assert!(!header.has_next());
129 assert!(!header.has_metadata());
130 assert!(!header.has_follows());
131 assert!(!header.has_ignore());
132
133 Ok(())
134 }
135
136 #[test]
137 fn test_payload_header() -> Result<()> {
138 let frame = include_bytes!("../../testdata/frame.payload.bin");
139 let header = FrameHeader::from_bytes(frame[0..Frame::LEN_HEADER].into());
140 print_binary(header.as_bytes());
141 assert!(header.has_metadata());
142 Ok(())
143 }
144
145 #[test]
146 fn test_header() -> Result<()> {
147 let header = FrameHeader::from_bytes(vec![0u8, 0, 4, 210, 25, 0].into());
148 print_binary(header.as_bytes());
149 println!("{}", header);
150 println!("{:?}", header.as_bytes());
151 assert!(header.has_metadata());
152 Ok(())
153 }
154
155 #[test]
156 fn test_header_no_flags() -> Result<()> {
157 let header = FrameHeader::new(0, FrameType::RequestStream, 0);
158 print_binary(header.as_bytes());
159 println!("{}", header);
160 println!("{:?}", header.as_bytes());
161 assert!(!header.has_metadata());
162 assert!(!header.has_next());
163 assert!(!header.has_complete());
164 assert!(!header.has_metadata());
165 assert!(!header.has_ignore());
166 Ok(())
167 }
168
169 #[test]
170 fn test_header_metadata() -> Result<()> {
171 let header = FrameHeader::new(0, FrameType::RequestStream, Frame::FLAG_METADATA);
172 print_binary(header.as_bytes());
173 println!("{}", header);
174 println!("{:?}", header.as_bytes());
175 assert!(header.has_metadata());
176 assert!(!header.has_next());
177 assert!(!header.has_complete());
178 assert!(!header.has_follows());
179 assert!(!header.has_ignore());
180 Ok(())
181 }
182
183 #[test]
184 fn test_header_next() -> Result<()> {
185 let header = FrameHeader::new(0, FrameType::RequestStream, Frame::FLAG_NEXT);
186 print_binary(header.as_bytes());
187 println!("{}", header);
188 println!("{:?}", header.as_bytes());
189 assert!(!header.has_metadata());
190 assert!(header.has_next());
191 assert!(!header.has_complete());
192 assert!(!header.has_follows());
193 assert!(!header.has_ignore());
194 Ok(())
195 }
196
197 #[test]
198 fn test_header_complete() -> Result<()> {
199 let header = FrameHeader::new(0, FrameType::RequestStream, Frame::FLAG_COMPLETE);
200 print_binary(header.as_bytes());
201 println!("{}", header);
202 println!("{:?}", header.as_bytes());
203 assert!(!header.has_metadata());
204 assert!(!header.has_next());
205 assert!(header.has_complete());
206 assert!(!header.has_follows());
207 assert!(!header.has_ignore());
208 Ok(())
209 }
210
211 #[test]
212 fn test_header_ignore() -> Result<()> {
213 let header = FrameHeader::new(0, FrameType::RequestStream, Frame::FLAG_IGNORE);
214 print_binary(header.as_bytes());
215 println!("{}", header);
216 println!("{:?}", header.as_bytes());
217 assert!(!header.has_metadata());
218 assert!(!header.has_next());
219 assert!(!header.has_complete());
220 assert!(!header.has_follows());
221 assert!(header.has_ignore());
222 Ok(())
223 }
224
225 #[test]
226 fn test_header_follows() -> Result<()> {
227 let header = FrameHeader::new(0, FrameType::RequestStream, Frame::FLAG_FOLLOW);
228 print_binary(header.as_bytes());
229 println!("{}", header);
230 println!("{:?}", header.as_bytes());
231 assert!(!header.has_metadata());
232 assert!(!header.has_next());
233 assert!(!header.has_complete());
234 assert!(header.has_follows());
235 assert!(!header.has_ignore());
236 Ok(())
237 }
238
239 }