wtransport_proto/capsule/
close_wt_session.rs

1use crate::capsule::Capsule;
2use crate::capsule::CapsuleKind;
3use crate::error::ErrorCode;
4use crate::varint::VarInt;
5
6/// Capsules for WebTransport session termination.
7#[derive(Debug)]
8pub struct CloseWebTransportSession {
9    error_code: u32,
10    reason: String,
11}
12
13impl CloseWebTransportSession {
14    /// Parses from [`Capsule`].
15    ///
16    /// # Panics
17    ///
18    /// Panics if `capsule` is not
19    /// [`CloseWebTransportSession`](CapsuleKind::CloseWebtransportsession) type.
20    pub fn with_capsule(capsule: &Capsule) -> Result<Self, ErrorCode> {
21        const MAX_REASON_LEN: usize = 1024;
22
23        assert!(matches!(
24            capsule.kind(),
25            CapsuleKind::CloseWebTransportSession
26        ));
27
28        let payload = capsule.payload();
29
30        if payload.len() < 4 || payload.len() > 4 + MAX_REASON_LEN {
31            return Err(ErrorCode::Datagram);
32        }
33
34        let error_code =
35            u32::from_be_bytes(payload[..4].try_into().expect("4B to u32 should succeed"));
36        let reason = std::str::from_utf8(&payload[4..])
37            .map_err(|_| ErrorCode::Datagram)?
38            .to_string();
39
40        Ok(Self { error_code, reason })
41    }
42
43    /// Returns the error code sent over this capsule.
44    pub fn error_code(&self) -> VarInt {
45        VarInt::from_u32(self.error_code)
46    }
47
48    /// Returns the reason sent over this capsule.
49    pub fn reason(&self) -> &str {
50        &self.reason
51    }
52}