wtransport_proto/capsule/
mod.rs1use crate::bytes::BytesReader;
2use crate::frame::Frame;
3use crate::frame::FrameKind;
4use crate::varint::VarInt;
5
6#[derive(Copy, Clone, Debug)]
8pub enum CapsuleKind {
9 CloseWebTransportSession,
11}
12
13impl CapsuleKind {
14 const fn parse(id: VarInt) -> Option<Self> {
15 match id {
16 capsule_types::CAPSULE_TYPE_CLOSE_WEBTRANSPORT_SESSION => {
17 Some(CapsuleKind::CloseWebTransportSession)
18 }
19 _ => None,
20 }
21 }
22}
23
24#[derive(Debug)]
26pub struct Capsule<'a> {
27 kind: CapsuleKind,
28 payload: &'a [u8],
29}
30
31impl<'a> Capsule<'a> {
32 pub fn with_frame(frame: &'a Frame<'a>) -> Option<Self> {
38 assert!(matches!(frame.kind(), FrameKind::Data));
39
40 let mut payload = frame.payload();
41 let kind = CapsuleKind::parse(payload.get_varint()?)?;
42 let payload_length = payload.get_varint()?;
43 let payload = payload.get_bytes(payload_length.into_inner() as usize)?;
44
45 Some(Self { kind, payload })
46 }
47
48 pub fn kind(&self) -> CapsuleKind {
50 self.kind
51 }
52
53 pub fn payload(&self) -> &[u8] {
55 self.payload
56 }
57}
58
59mod capsule_types {
60 use crate::varint::VarInt;
61
62 pub const CAPSULE_TYPE_CLOSE_WEBTRANSPORT_SESSION: VarInt = VarInt::from_u32(0x2843);
63}
64
65pub mod capsules {
67 pub use super::close_wt_session::CloseWebTransportSession;
68}
69
70mod close_wt_session;
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn capsule_close_wt_session() {
78 let frame = Frame::new_data(vec![104, 67, 4, 0, 0, 0, 0u8].into());
79 let capsule = Capsule::with_frame(&frame).unwrap();
80 let close =
81 capsules::CloseWebTransportSession::with_capsule(&capsule).expect("Should parse");
82 assert_eq!(close.error_code(), VarInt::from_u32(0));
83 assert_eq!(close.reason(), "");
84 }
85}