1 use super::StreamId;
2 
3 use bytes::BufMut;
4 
5 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
6 pub struct Head {
7     kind: Kind,
8     flag: u8,
9     stream_id: StreamId,
10 }
11 
12 #[repr(u8)]
13 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
14 pub 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 
30 impl Head {
new(kind: Kind, flag: u8, stream_id: StreamId) -> Head31     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
parse(header: &[u8]) -> Head40     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 
stream_id(&self) -> StreamId50     pub fn stream_id(&self) -> StreamId {
51         self.stream_id
52     }
53 
kind(&self) -> Kind54     pub fn kind(&self) -> Kind {
55         self.kind
56     }
57 
flag(&self) -> u858     pub fn flag(&self) -> u8 {
59         self.flag
60     }
61 
encode_len(&self) -> usize62     pub fn encode_len(&self) -> usize {
63         super::HEADER_LEN
64     }
65 
encode<T: BufMut>(&self, payload_len: usize, dst: &mut T)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 
78 impl Kind {
new(byte: u8) -> Kind79     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