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#[derive(Debug)]
10pub struct Datagram {
11 quic_dgram: Bytes,
12 payload_offset: usize,
13 session_id: SessionId,
14}
15
16impl Datagram {
17 #[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 #[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}