Skip to main content

moqtap_codec/
types.rs

1use crate::varint::VarInt;
2use bytes::{Buf, BufMut};
3
4/// Track Namespace: ordered N-tuple of byte-string elements (1 <= N <= 32).
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct TrackNamespace(pub Vec<Vec<u8>>);
7
8/// Full Track Name: namespace + track name.
9/// Maximum total size: 4096 bytes.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct FullTrackName {
12    pub namespace: TrackNamespace,
13    pub track_name: Vec<u8>,
14}
15
16/// Location within a track: (Group, Object).
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct Location {
19    pub group: VarInt,
20    pub object: VarInt,
21}
22
23/// Object status values (draft-14).
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25#[repr(u8)]
26pub enum ObjectStatus {
27    Normal = 0x0,
28    EndOfGroup = 0x1,
29    EndOfTrack = 0x2,
30    DoesNotExist = 0x3,
31}
32
33/// Group ordering preference.
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35#[repr(u8)]
36pub enum GroupOrder {
37    Publisher = 0x0,
38    Ascending = 0x1,
39    Descending = 0x2,
40}
41
42/// Forwarding preference for objects.
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44#[repr(u8)]
45pub enum ForwardingPreference {
46    Object = 0x0,
47    Datagram = 0x1,
48}
49
50/// Whether content exists (used in SUBSCRIBE_OK).
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52#[repr(u8)]
53pub enum ContentExists {
54    NoLargestLocation = 0,
55    HasLargestLocation = 1,
56}
57
58/// Forward state (0 = don't forward, 1 = forward).
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60#[repr(u8)]
61pub enum Forward {
62    DontForward = 0,
63    Forward = 1,
64}
65
66/// Subscription filter types (draft-14).
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68#[repr(u8)]
69pub enum FilterType {
70    NextGroupStart = 0x1,
71    LargestObject = 0x2,
72    AbsoluteStart = 0x3,
73    AbsoluteRange = 0x4,
74}
75
76/// Authorization token alias types.
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78#[repr(u8)]
79pub enum TokenAliasType {
80    Delete = 0x0,
81    Register = 0x1,
82    UseAlias = 0x2,
83    UseValue = 0x3,
84}
85
86impl TrackNamespace {
87    pub fn encode(&self, buf: &mut impl BufMut) {
88        let n = self.0.len();
89        VarInt::from_u64(n as u64).unwrap().encode(buf);
90        for elem in &self.0 {
91            VarInt::from_u64(elem.len() as u64).unwrap().encode(buf);
92            buf.put_slice(elem);
93        }
94    }
95
96    pub fn decode(buf: &mut impl Buf) -> Result<Self, crate::message::CodecError> {
97        let n = VarInt::decode(buf)?.into_inner() as usize;
98        if n == 0 || n > crate::message::MAX_NAMESPACE_TUPLE_SIZE {
99            return Err(crate::message::CodecError::InvalidNamespaceTupleSize(n));
100        }
101        let mut elements = Vec::with_capacity(n);
102        for _ in 0..n {
103            let len = VarInt::decode(buf)?.into_inner() as usize;
104            if buf.remaining() < len {
105                return Err(crate::message::CodecError::UnexpectedEnd);
106            }
107            let mut data = vec![0u8; len];
108            buf.copy_to_slice(&mut data);
109            elements.push(data);
110        }
111        Ok(TrackNamespace(elements))
112    }
113}
114
115impl Location {
116    pub fn encode(&self, buf: &mut impl BufMut) {
117        self.group.encode(buf);
118        self.object.encode(buf);
119    }
120
121    pub fn decode(buf: &mut impl Buf) -> Result<Self, crate::message::CodecError> {
122        let group = VarInt::decode(buf)?;
123        let object = VarInt::decode(buf)?;
124        Ok(Location { group, object })
125    }
126}
127
128impl ObjectStatus {
129    pub fn from_u8(v: u8) -> Option<Self> {
130        match v {
131            0x0 => Some(ObjectStatus::Normal),
132            0x1 => Some(ObjectStatus::EndOfGroup),
133            0x2 => Some(ObjectStatus::EndOfTrack),
134            0x3 => Some(ObjectStatus::DoesNotExist),
135            _ => None,
136        }
137    }
138}
139
140impl GroupOrder {
141    pub fn from_u8(v: u8) -> Option<Self> {
142        match v {
143            0x0 => Some(GroupOrder::Publisher),
144            0x1 => Some(GroupOrder::Ascending),
145            0x2 => Some(GroupOrder::Descending),
146            _ => None,
147        }
148    }
149}
150
151impl ForwardingPreference {
152    pub fn from_u8(v: u8) -> Option<Self> {
153        match v {
154            0x0 => Some(ForwardingPreference::Object),
155            0x1 => Some(ForwardingPreference::Datagram),
156            _ => None,
157        }
158    }
159}
160
161impl FilterType {
162    pub fn from_u8(v: u8) -> Option<Self> {
163        match v {
164            0x1 => Some(FilterType::NextGroupStart),
165            0x2 => Some(FilterType::LargestObject),
166            0x3 => Some(FilterType::AbsoluteStart),
167            0x4 => Some(FilterType::AbsoluteRange),
168            _ => None,
169        }
170    }
171}