wasmrs_frames/frames/
header.rs

1use 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  // #[test]
240  // fn test_flags() -> Result<()> {
241  //     let header = FrameHeader::new(0, FrameType::RequestStream, FRAME_FLAG_IGNORE);
242  //     print_binary(&FRAME_FLAG_IGNORE.to_be_bytes());
243  //     print_binary(&FRAME_FLAG_NEXT.to_be_bytes());
244  //     print_binary(&FRAME_FLAG_COMPLETE.to_be_bytes());
245  //     print_binary(&FRAME_FLAG_FOLLOWS.to_be_bytes());
246  //     print_binary(&FRAME_FLAG_METADATA.to_be_bytes());
247  //     panic!();
248  //     Ok(())
249  // }
250}