1use bytes::{Buf, BufMut};
4
5use crate::grease::is_grease_value;
6use crate::{VarInt, VarIntUnexpectedEnd};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct Frame(pub VarInt);
11
12impl Frame {
13 pub fn decode<B: Buf>(buf: &mut B) -> Result<Self, VarIntUnexpectedEnd> {
15 let typ = VarInt::decode(buf)?;
16 Ok(Frame(typ))
17 }
18
19 pub fn encode<B: BufMut>(&self, buf: &mut B) {
21 self.0.encode(buf)
22 }
23
24 pub fn is_grease(&self) -> bool {
26 is_grease_value(self.0.into_inner())
27 }
28
29 pub fn read<B: Buf>(
31 buf: &mut B,
32 ) -> Result<(Frame, bytes::buf::Take<&mut B>), VarIntUnexpectedEnd> {
33 let typ = Frame::decode(buf)?;
34 let size = VarInt::decode(buf)?;
35
36 let mut limit = Buf::take(buf, size.into_inner() as usize);
37 if limit.remaining() < limit.limit() {
38 return Err(VarIntUnexpectedEnd);
39 }
40
41 if typ.is_grease() {
43 limit.advance(limit.limit());
44 return Self::read(limit.into_inner());
45 }
46
47 Ok((typ, limit))
48 }
49
50 pub const fn from_u32(value: u32) -> Self {
52 Self(VarInt::from_u32(value))
53 }
54
55 pub const DATA: Frame = Frame::from_u32(0x00);
58 pub const HEADERS: Frame = Frame::from_u32(0x01);
60 pub const SETTINGS: Frame = Frame::from_u32(0x04);
62 pub const WEBTRANSPORT: Frame = Frame::from_u32(0x41);
64}