Skip to main content

moqtap_codec/
kvp.rs

1use crate::varint::VarInt;
2use bytes::{Buf, BufMut};
3
4/// Maximum value length for a Key-Value Pair: 2^16 - 1 bytes.
5pub const MAX_KVP_VALUE_LEN: usize = 65535;
6
7/// Value of a Key-Value Pair.
8/// Even key type -> varint value (no length field).
9/// Odd key type -> length-prefixed bytes.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum KvpValue {
12    Varint(VarInt),
13    Bytes(Vec<u8>),
14}
15
16/// A MoQT Key-Value Pair (used for parameters in control messages).
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct KeyValuePair {
19    pub key: VarInt,
20    pub value: KvpValue,
21}
22
23#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)]
24pub enum KvpError {
25    #[error("odd key type requires length-prefixed value")]
26    MissingLength,
27    #[error("value length {0} exceeds maximum ({MAX_KVP_VALUE_LEN})")]
28    ValueTooLong(usize),
29    #[error("insufficient bytes")]
30    UnexpectedEnd,
31    #[error("varint error: {0}")]
32    VarInt(#[from] crate::varint::VarIntError),
33}
34
35impl KeyValuePair {
36    /// Encode a single key-value pair.
37    pub fn encode(&self, buf: &mut impl BufMut) {
38        self.key.encode(buf);
39        match &self.value {
40            KvpValue::Varint(v) => {
41                // Even key: write varint value directly
42                v.encode(buf);
43            }
44            KvpValue::Bytes(bytes) => {
45                // Odd key: write length-prefixed bytes
46                VarInt::from_u64(bytes.len() as u64).unwrap().encode(buf);
47                buf.put_slice(bytes);
48            }
49        }
50    }
51
52    /// Decode a single key-value pair.
53    pub fn decode(buf: &mut impl Buf) -> Result<Self, KvpError> {
54        let key = VarInt::decode(buf)?;
55        let key_val = key.into_inner();
56
57        if key_val % 2 == 0 {
58            // Even key: value is a varint
59            let value = VarInt::decode(buf)?;
60            Ok(KeyValuePair { key, value: KvpValue::Varint(value) })
61        } else {
62            // Odd key: value is length-prefixed bytes
63            let len = VarInt::decode(buf)?.into_inner() as usize;
64            if len > MAX_KVP_VALUE_LEN {
65                return Err(KvpError::ValueTooLong(len));
66            }
67            if buf.remaining() < len {
68                return Err(KvpError::UnexpectedEnd);
69            }
70            let mut bytes = vec![0u8; len];
71            buf.copy_to_slice(&mut bytes);
72            Ok(KeyValuePair { key, value: KvpValue::Bytes(bytes) })
73        }
74    }
75
76    /// Encode a list of key-value pairs (count-prefixed).
77    pub fn encode_list(pairs: &[KeyValuePair], buf: &mut impl BufMut) {
78        VarInt::from_u64(pairs.len() as u64).unwrap().encode(buf);
79        for pair in pairs {
80            pair.encode(buf);
81        }
82    }
83
84    /// Decode a list of key-value pairs (count-prefixed).
85    pub fn decode_list(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, KvpError> {
86        let count = VarInt::decode(buf)?.into_inner() as usize;
87        let mut pairs = Vec::with_capacity(count);
88        for _ in 0..count {
89            pairs.push(KeyValuePair::decode(buf)?);
90        }
91        Ok(pairs)
92    }
93}