use bytes::{Buf, BufMut};
use crate::grease::is_grease_value;
use crate::{VarInt, VarIntUnexpectedEnd};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Frame(pub VarInt);
impl Frame {
pub fn decode<B: Buf>(buf: &mut B) -> Result<Self, VarIntUnexpectedEnd> {
let typ = VarInt::decode(buf)?;
Ok(Frame(typ))
}
pub fn encode<B: BufMut>(&self, buf: &mut B) {
self.0.encode(buf)
}
pub fn is_grease(&self) -> bool {
is_grease_value(self.0.into_inner())
}
pub fn read<B: Buf>(
buf: &mut B,
) -> Result<(Frame, bytes::buf::Take<&mut B>), VarIntUnexpectedEnd> {
let typ = Frame::decode(buf)?;
let size = VarInt::decode(buf)?;
let mut limit = Buf::take(buf, size.into_inner() as usize);
if limit.remaining() < limit.limit() {
return Err(VarIntUnexpectedEnd);
}
if typ.is_grease() {
limit.advance(limit.limit());
return Self::read(limit.into_inner());
}
Ok((typ, limit))
}
pub const fn from_u32(value: u32) -> Self {
Self(VarInt::from_u32(value))
}
pub const DATA: Frame = Frame::from_u32(0x00);
pub const HEADERS: Frame = Frame::from_u32(0x01);
pub const SETTINGS: Frame = Frame::from_u32(0x04);
pub const WEBTRANSPORT: Frame = Frame::from_u32(0x41);
}