wtransport/
datagram.rs

1use crate::SessionId;
2use bytes::Bytes;
3use std::ops::Deref;
4use wtransport_proto::datagram::Datagram as H3Datagram;
5use wtransport_proto::error::ErrorCode;
6use wtransport_proto::ids::QStreamId;
7
8/// An application Datagram.
9#[derive(Debug)]
10pub struct Datagram {
11    quic_dgram: Bytes,
12    payload_offset: usize,
13    session_id: SessionId,
14}
15
16impl Datagram {
17    /// Returns the datagram payload.
18    #[inline(always)]
19    pub fn payload(&self) -> Bytes {
20        self.quic_dgram.slice(self.payload_offset..)
21    }
22
23    pub(crate) fn read(quic_dgram: Bytes) -> Result<Self, ErrorCode> {
24        let h3dgram = H3Datagram::read(&quic_dgram)?;
25        let payload_offset = quic_dgram.len() - h3dgram.payload().len();
26        let session_id = h3dgram.qstream_id().into_session_id();
27
28        Ok(Self {
29            quic_dgram,
30            payload_offset,
31            session_id,
32        })
33    }
34
35    pub(crate) fn write(session_id: SessionId, payload: &[u8]) -> Self {
36        let h3dgram = H3Datagram::new(QStreamId::from_session_id(session_id), payload);
37
38        let mut buffer = vec![0; h3dgram.write_size()].into_boxed_slice();
39        h3dgram.write(&mut buffer).expect("Preallocated capacity");
40
41        let quic_dgram = Bytes::from(buffer);
42
43        let payload_offset = quic_dgram.len() - payload.len();
44
45        Self {
46            quic_dgram,
47            payload_offset,
48            session_id,
49        }
50    }
51
52    #[inline(always)]
53    pub(crate) fn header_size(session_id: SessionId) -> usize {
54        H3Datagram::header_size(QStreamId::from_session_id(session_id))
55    }
56
57    /// Returns the associated [`SessionId`].
58    #[inline(always)]
59    pub fn session_id(&self) -> SessionId {
60        self.session_id
61    }
62
63    #[inline(always)]
64    pub(crate) fn into_quic_bytes(self) -> Bytes {
65        self.quic_dgram
66    }
67}
68
69impl Deref for Datagram {
70    type Target = [u8];
71
72    #[inline(always)]
73    fn deref(&self) -> &Self::Target {
74        &self.quic_dgram[self.payload_offset..]
75    }
76}