rtc_shared/marshal/mod.rs
1use bytes::{Buf, BytesMut};
2
3use crate::error::{Error, Result};
4
5/// The encoded size of a value, in bytes.
6///
7/// Implemented alongside [`Marshal`]/[`Unmarshal`] so a caller can size a buffer before
8/// encoding, and so nested codecs can compute offsets without encoding twice.
9pub trait MarshalSize: Send + Sync {
10 /// The number of bytes [`Marshal::marshal_to`] will write for this value.
11 fn marshal_size(&self) -> usize;
12}
13
14/// Encodes a value into its wire format.
15///
16/// Every protocol codec in the stack — STUN, RTP, RTCP, SDP, DTLS, SCTP — implements this
17/// so that higher layers can serialize uniformly.
18pub trait Marshal: MarshalSize {
19 /// Encodes into `buf`, returning the number of bytes written.
20 ///
21 /// # Errors
22 ///
23 /// Fails if `buf` is shorter than [`MarshalSize::marshal_size`], or if the value itself is
24 /// not encodable (an out-of-range field, for instance).
25 fn marshal_to(&self, buf: &mut [u8]) -> Result<usize>;
26
27 /// Encodes into a freshly allocated buffer sized by [`MarshalSize::marshal_size`].
28 ///
29 /// # Errors
30 ///
31 /// Propagates any failure from [`Self::marshal_to`].
32 fn marshal(&self) -> Result<BytesMut> {
33 let l = self.marshal_size();
34 let mut buf = BytesMut::with_capacity(l);
35 buf.resize(l, 0);
36 let n = self.marshal_to(&mut buf)?;
37 if n != l {
38 Err(Error::Other(format!(
39 "marshal_to output size {n}, but expect {l}"
40 )))
41 } else {
42 Ok(buf)
43 }
44 }
45}
46
47/// Decodes a value from its wire format.
48pub trait Unmarshal: MarshalSize {
49 /// Decodes one value from `buf`, advancing it past the bytes consumed.
50 ///
51 /// # Errors
52 ///
53 /// Fails if `buf` is truncated, or if its contents are not a valid encoding of `Self`.
54 fn unmarshal<B>(buf: &mut B) -> Result<Self>
55 where
56 Self: Sized,
57 B: Buf;
58}