use bytes::{Buf, Bytes};
use h3::{error::Code, proto::varint::VarInt, quic::StreamId, Error};
pub struct Datagram<B = Bytes> {
stream_id: StreamId,
payload: B,
}
impl<B> Datagram<B>
where
B: Buf,
{
pub fn new(stream_id: StreamId, payload: B) -> Self {
assert!(
stream_id.into_inner() % 4 == 0,
"StreamId is not divisible by 4"
);
Self { stream_id, payload }
}
pub fn decode(mut buf: B) -> Result<Self, Error> {
let q_stream_id = VarInt::decode(&mut buf)
.map_err(|_| Code::H3_DATAGRAM_ERROR.with_cause("Malformed datagram frame"))?;
let stream_id = StreamId::try_from(u64::from(q_stream_id) * 4)
.map_err(|_| Code::H3_DATAGRAM_ERROR.with_cause("Invalid stream id"))?;
let payload = buf;
Ok(Self { stream_id, payload })
}
#[inline]
pub fn stream_id(&self) -> StreamId {
self.stream_id
}
#[inline]
pub fn payload(&self) -> &B {
&self.payload
}
pub fn encode<D: bytes::BufMut>(self, buf: &mut D) {
(VarInt::from(self.stream_id) / 4).encode(buf);
buf.put(self.payload);
}
pub fn into_payload(self) -> B {
self.payload
}
}