use super::StreamId; use bytes::{BufMut, BigEndian}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Head { kind: Kind, flag: u8, stream_id: StreamId, } #[repr(u8)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum Kind { Data = 0, Headers = 1, Priority = 2, Reset = 3, Settings = 4, PushPromise = 5, Ping = 6, GoAway = 7, WindowUpdate = 8, Continuation = 9, Unknown, } // ===== impl Head ===== impl Head { pub fn new(kind: Kind, flag: u8, stream_id: StreamId) -> Head { Head { kind: kind, flag: flag, stream_id: stream_id, } } /// Parse an HTTP/2.0 frame header pub fn parse(header: &[u8]) -> Head { Head { kind: Kind::new(header[3]), flag: header[4], stream_id: StreamId::parse(&header[5..]), } } pub fn stream_id(&self) -> StreamId { self.stream_id } pub fn kind(&self) -> Kind { self.kind } pub fn flag(&self) -> u8 { self.flag } pub fn encode_len(&self) -> usize { super::HEADER_LEN } pub fn encode(&self, payload_len: usize, dst: &mut T) { debug_assert!(self.encode_len() <= dst.remaining_mut()); dst.put_uint::(payload_len as u64, 3); dst.put_u8(self.kind as u8); dst.put_u8(self.flag); dst.put_u32::(self.stream_id.into()); } } // ===== impl Kind ===== impl Kind { pub fn new(byte: u8) -> Kind { match byte { 0 => Kind::Data, 1 => Kind::Headers, 2 => Kind::Priority, 3 => Kind::Reset, 4 => Kind::Settings, 5 => Kind::PushPromise, 6 => Kind::Ping, 7 => Kind::GoAway, 8 => Kind::WindowUpdate, 9 => Kind::Continuation, _ => Kind::Unknown, } } }