1use super::StreamId;
2
3use bytes::BufMut;
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq)]
6pub struct Head {
7 kind: Kind,
8 flag: u8,
9 stream_id: StreamId,
10}
11
12#[repr(u8)]
13#[derive(Debug, Copy, Clone, PartialEq, Eq)]
14pub enum Kind {
15 Data = 0,
16 Headers = 1,
17 Priority = 2,
18 Reset = 3,
19 Settings = 4,
20 PushPromise = 5,
21 Ping = 6,
22 GoAway = 7,
23 WindowUpdate = 8,
24 Continuation = 9,
25 Unknown,
26}
27
28// ===== impl Head =====
29
30impl Head {
31 pub fn new(kind: Kind, flag: u8, stream_id: StreamId) -> Head {
32 Head {
33 kind,
34 flag,
35 stream_id,
36 }
37 }
38
39 /// Parse an HTTP/2 frame header
40 pub fn parse(header: &[u8]) -> Head {
41 let (stream_id, _) = StreamId::parse(&header[5..]);
42
43 Head {
44 kind: Kind::new(header[3]),
45 flag: header[4],
46 stream_id,
47 }
48 }
49
50 pub fn stream_id(&self) -> StreamId {
51 self.stream_id
52 }
53
54 pub fn kind(&self) -> Kind {
55 self.kind
56 }
57
58 pub fn flag(&self) -> u8 {
59 self.flag
60 }
61
62 pub fn encode_len(&self) -> usize {
63 super::HEADER_LEN
64 }
65
66 pub fn encode<T: BufMut>(&self, payload_len: usize, dst: &mut T) {
67 debug_assert!(self.encode_len() <= dst.remaining_mut());
68
69 dst.put_uint(payload_len as u64, 3);
70 dst.put_u8(self.kind as u8);
71 dst.put_u8(self.flag);
72 dst.put_u32(self.stream_id.into());
73 }
74}
75
76// ===== impl Kind =====
77
78impl Kind {
79 pub fn new(byte: u8) -> Kind {
80 match byte {
81 0 => Kind::Data,
82 1 => Kind::Headers,
83 2 => Kind::Priority,
84 3 => Kind::Reset,
85 4 => Kind::Settings,
86 5 => Kind::PushPromise,
87 6 => Kind::Ping,
88 7 => Kind::GoAway,
89 8 => Kind::WindowUpdate,
90 9 => Kind::Continuation,
91 _ => Kind::Unknown,
92 }
93 }
94}
95