Skip to main content

moqtap_codec/draft13/
fields.rs

1use crate::draft13::message::*;
2use crate::fields::{FieldMap as Map, FieldValue as Value};
3use crate::kvp::{KeyValuePair, KvpValue};
4use crate::types::*;
5use crate::varint::VarInt;
6
7fn vi(v: u64) -> Value {
8    Value::Uint(v)
9}
10
11fn ns_to_json(ns: &TrackNamespace) -> Value {
12    Value::Array(
13        ns.0.iter().map(|e| Value::Text(String::from_utf8_lossy(e).into_owned())).collect(),
14    )
15}
16
17fn loc_to_json(loc: &Location) -> Value {
18    let mut o = Map::new();
19    o.insert("group".into(), vi(loc.group.into_inner()));
20    o.insert("object".into(), vi(loc.object.into_inner()));
21    Value::Map(o)
22}
23
24fn auth_token_to_json(bytes: &[u8]) -> Value {
25    let mut buf = bytes;
26    let alias_type = VarInt::decode(&mut buf).unwrap();
27    let at = alias_type.into_inner();
28    let mut o = Map::new();
29    o.insert("alias_type".into(), vi(at));
30    match at {
31        // DELETE, USE_ALIAS: only token_alias
32        0 | 2 => {
33            let token_alias = VarInt::decode(&mut buf).unwrap();
34            o.insert("token_alias".into(), vi(token_alias.into_inner()));
35        }
36        // REGISTER: token_alias + token_type + token_value
37        1 => {
38            let token_alias = VarInt::decode(&mut buf).unwrap();
39            let token_type = VarInt::decode(&mut buf).unwrap();
40            o.insert("token_alias".into(), vi(token_alias.into_inner()));
41            o.insert("token_type".into(), vi(token_type.into_inner()));
42            o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
43        }
44        // USE_VALUE (3) or other: token_type + token_value
45        _ => {
46            let token_type = VarInt::decode(&mut buf).unwrap();
47            o.insert("token_type".into(), vi(token_type.into_inner()));
48            o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
49        }
50    }
51    Value::Map(o)
52}
53
54fn kvp_to_json_setup(params: &[KeyValuePair]) -> Value {
55    let mut obj = Map::new();
56    for p in params {
57        let key = p.key.into_inner();
58        match (key, &p.value) {
59            (0x01, KvpValue::Bytes(b)) => {
60                obj.insert("path".into(), Value::Text(String::from_utf8_lossy(b).into_owned()));
61            }
62            (0x02, KvpValue::Varint(v)) => {
63                obj.insert("max_request_id".into(), vi(v.into_inner()));
64            }
65            (0x03, KvpValue::Bytes(b)) => {
66                obj.insert("authorization_token".into(), auth_token_to_json(b));
67            }
68            (0x04, KvpValue::Varint(v)) => {
69                obj.insert("max_auth_token_cache_size".into(), vi(v.into_inner()));
70            }
71            _ => {}
72        }
73    }
74    Value::Map(obj)
75}
76
77fn kvp_to_json_msg(params: &[KeyValuePair]) -> Value {
78    let mut obj = Map::new();
79    for p in params {
80        let key = p.key.into_inner();
81        match (key, &p.value) {
82            (0x03, KvpValue::Bytes(b)) => {
83                obj.insert("authorization_token".into(), auth_token_to_json(b));
84            }
85            (0x02, KvpValue::Varint(v)) => {
86                obj.insert("delivery_timeout".into(), vi(v.into_inner()));
87            }
88            (0x04, KvpValue::Varint(v)) => {
89                obj.insert("max_cache_duration".into(), vi(v.into_inner()));
90            }
91            _ => {}
92        }
93    }
94    Value::Map(obj)
95}
96
97/// This draft's field names for a decoded control message.
98///
99/// Keys are the names this draft gives its fields, in the order it defines
100/// them. An optional field the message did not carry is absent rather than
101/// zero.
102pub fn message_fields(msg: &ControlMessage) -> Map {
103    let obj = match msg {
104        ControlMessage::ClientSetup(m) => {
105            let mut o = Map::new();
106            o.insert(
107                "supported_versions".into(),
108                Value::Array(m.supported_versions.iter().map(|v| vi(v.into_inner())).collect()),
109            );
110            o.insert("parameters".into(), kvp_to_json_setup(&m.parameters));
111            o
112        }
113        ControlMessage::ServerSetup(m) => {
114            let mut o = Map::new();
115            o.insert("selected_version".into(), vi(m.selected_version.into_inner()));
116            o.insert("parameters".into(), kvp_to_json_setup(&m.parameters));
117            o
118        }
119        ControlMessage::GoAway(m) => {
120            let mut o = Map::new();
121            o.insert(
122                "new_session_uri".into(),
123                Value::Text(String::from_utf8_lossy(&m.new_session_uri).into_owned()),
124            );
125            o
126        }
127        ControlMessage::MaxRequestId(m) => {
128            let mut o = Map::new();
129            o.insert("request_id".into(), vi(m.request_id.into_inner()));
130            o
131        }
132        ControlMessage::RequestsBlocked(m) => {
133            let mut o = Map::new();
134            o.insert("maximum_request_id".into(), vi(m.maximum_request_id.into_inner()));
135            o
136        }
137        ControlMessage::Subscribe(m) => {
138            let mut o = Map::new();
139            o.insert("request_id".into(), vi(m.request_id.into_inner()));
140            o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
141            o.insert(
142                "track_name".into(),
143                Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
144            );
145            o.insert("subscriber_priority".into(), vi(m.subscriber_priority as u64));
146            o.insert("group_order".into(), vi(m.group_order as u64));
147            o.insert("forward".into(), vi(m.forward as u64));
148            o.insert("filter_type".into(), vi(m.filter_type as u64));
149            if let Some(sg) = &m.start_group {
150                o.insert("start_group".into(), vi(sg.into_inner()));
151            }
152            if let Some(so) = &m.start_object {
153                o.insert("start_object".into(), vi(so.into_inner()));
154            }
155            if let Some(eg) = &m.end_group {
156                o.insert("end_group".into(), vi(eg.into_inner()));
157            }
158            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
159            o
160        }
161        ControlMessage::SubscribeOk(m) => {
162            let mut o = Map::new();
163            o.insert("request_id".into(), vi(m.request_id.into_inner()));
164            o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
165            o.insert("expires".into(), vi(m.expires.into_inner()));
166            o.insert("group_order".into(), vi(m.group_order as u64));
167            o.insert("content_exists".into(), vi(m.content_exists as u64));
168            if let Some(loc) = &m.largest_location {
169                o.insert("largest_location".into(), loc_to_json(loc));
170            }
171            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
172            o
173        }
174        ControlMessage::SubscribeError(m) => {
175            let mut o = Map::new();
176            o.insert("request_id".into(), vi(m.request_id.into_inner()));
177            o.insert("error_code".into(), vi(m.error_code.into_inner()));
178            o.insert(
179                "reason_phrase".into(),
180                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
181            );
182            o
183        }
184        ControlMessage::SubscribeUpdate(m) => {
185            let mut o = Map::new();
186            o.insert("request_id".into(), vi(m.request_id.into_inner()));
187            o.insert("start_group".into(), vi(m.start_group.into_inner()));
188            o.insert("start_object".into(), vi(m.start_object.into_inner()));
189            o.insert("end_group".into(), vi(m.end_group.into_inner()));
190            o.insert("subscriber_priority".into(), vi(m.subscriber_priority as u64));
191            o.insert("forward".into(), vi(m.forward as u64));
192            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
193            o
194        }
195        ControlMessage::SubscribeDone(m) => {
196            let mut o = Map::new();
197            o.insert("request_id".into(), vi(m.request_id.into_inner()));
198            o.insert("status_code".into(), vi(m.status_code.into_inner()));
199            o.insert("stream_count".into(), vi(m.stream_count.into_inner()));
200            o.insert(
201                "reason_phrase".into(),
202                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
203            );
204            o
205        }
206        ControlMessage::Unsubscribe(m) => {
207            let mut o = Map::new();
208            o.insert("request_id".into(), vi(m.request_id.into_inner()));
209            o
210        }
211        ControlMessage::Announce(m) => {
212            let mut o = Map::new();
213            o.insert("request_id".into(), vi(m.request_id.into_inner()));
214            o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
215            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
216            o
217        }
218        ControlMessage::AnnounceOk(m) => {
219            let mut o = Map::new();
220            o.insert("request_id".into(), vi(m.request_id.into_inner()));
221            o
222        }
223        ControlMessage::AnnounceError(m) => {
224            let mut o = Map::new();
225            o.insert("request_id".into(), vi(m.request_id.into_inner()));
226            o.insert("error_code".into(), vi(m.error_code.into_inner()));
227            o.insert(
228                "reason_phrase".into(),
229                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
230            );
231            o
232        }
233        ControlMessage::AnnounceCancel(m) => {
234            let mut o = Map::new();
235            o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
236            o.insert("error_code".into(), vi(m.error_code.into_inner()));
237            o.insert(
238                "reason_phrase".into(),
239                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
240            );
241            o
242        }
243        ControlMessage::Unannounce(m) => {
244            let mut o = Map::new();
245            o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
246            o
247        }
248        ControlMessage::SubscribeNamespace(m) => {
249            let mut o = Map::new();
250            o.insert("request_id".into(), vi(m.request_id.into_inner()));
251            o.insert("track_namespace_prefix".into(), ns_to_json(&m.track_namespace_prefix));
252            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
253            o
254        }
255        ControlMessage::SubscribeNamespaceOk(m) => {
256            let mut o = Map::new();
257            o.insert("request_id".into(), vi(m.request_id.into_inner()));
258            o
259        }
260        ControlMessage::SubscribeNamespaceError(m) => {
261            let mut o = Map::new();
262            o.insert("request_id".into(), vi(m.request_id.into_inner()));
263            o.insert("error_code".into(), vi(m.error_code.into_inner()));
264            o.insert(
265                "reason_phrase".into(),
266                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
267            );
268            o
269        }
270        ControlMessage::UnsubscribeNamespace(m) => {
271            let mut o = Map::new();
272            o.insert("track_namespace_prefix".into(), ns_to_json(&m.track_namespace_prefix));
273            o
274        }
275        ControlMessage::TrackStatus(m) => {
276            let mut o = Map::new();
277            o.insert("request_id".into(), vi(m.request_id.into_inner()));
278            o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
279            o.insert(
280                "track_name".into(),
281                Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
282            );
283            o.insert("subscriber_priority".into(), vi(m.subscriber_priority as u64));
284            o.insert("group_order".into(), vi(m.group_order as u64));
285            o.insert("forward".into(), vi(m.forward as u64));
286            o.insert("filter_type".into(), vi(m.filter_type as u64));
287            if let Some(sg) = &m.start_group {
288                o.insert("start_group".into(), vi(sg.into_inner()));
289            }
290            if let Some(so) = &m.start_object {
291                o.insert("start_object".into(), vi(so.into_inner()));
292            }
293            if let Some(eg) = &m.end_group {
294                o.insert("end_group".into(), vi(eg.into_inner()));
295            }
296            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
297            o
298        }
299        ControlMessage::TrackStatusOk(m) => {
300            let mut o = Map::new();
301            o.insert("request_id".into(), vi(m.request_id.into_inner()));
302            o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
303            o.insert("expires".into(), vi(m.expires.into_inner()));
304            o.insert("group_order".into(), vi(m.group_order as u64));
305            o.insert("content_exists".into(), vi(m.content_exists as u64));
306            if let Some(loc) = &m.largest_location {
307                o.insert("largest_location".into(), loc_to_json(loc));
308            }
309            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
310            o
311        }
312        ControlMessage::TrackStatusError(m) => {
313            let mut o = Map::new();
314            o.insert("request_id".into(), vi(m.request_id.into_inner()));
315            o.insert("error_code".into(), vi(m.error_code.into_inner()));
316            o.insert(
317                "reason_phrase".into(),
318                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
319            );
320            o
321        }
322        ControlMessage::Fetch(m) => {
323            let mut o = Map::new();
324            o.insert("request_id".into(), vi(m.request_id.into_inner()));
325            o.insert("subscriber_priority".into(), vi(m.subscriber_priority as u64));
326            o.insert("group_order".into(), vi(m.group_order as u64));
327            o.insert("fetch_type".into(), vi(m.fetch_type as u64));
328            match &m.fetch_payload {
329                FetchPayload::Standalone {
330                    track_namespace,
331                    track_name,
332                    start_group,
333                    start_object,
334                    end_group,
335                    end_object,
336                } => {
337                    o.insert("track_namespace".into(), ns_to_json(track_namespace));
338                    o.insert(
339                        "track_name".into(),
340                        Value::Text(String::from_utf8_lossy(track_name).into_owned()),
341                    );
342                    o.insert("start_group".into(), vi(start_group.into_inner()));
343                    o.insert("start_object".into(), vi(start_object.into_inner()));
344                    o.insert("end_group".into(), vi(end_group.into_inner()));
345                    o.insert("end_object".into(), vi(end_object.into_inner()));
346                }
347                FetchPayload::Joining { joining_request_id, joining_start } => {
348                    // The key is the corpus's spelling, not this draft's. The
349                    // draft renamed the field to Joining Request ID; the shared
350                    // vector files still say joining_subscribe_id, and they are
351                    // maintained elsewhere, so the name is translated here
352                    // rather than changed there.
353                    o.insert("joining_subscribe_id".into(), vi(joining_request_id.into_inner()));
354                    o.insert("joining_start".into(), vi(joining_start.into_inner()));
355                }
356            }
357            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
358            o
359        }
360        ControlMessage::FetchOk(m) => {
361            let mut o = Map::new();
362            o.insert("request_id".into(), vi(m.request_id.into_inner()));
363            o.insert("group_order".into(), vi(m.group_order as u64));
364            o.insert("end_of_track".into(), vi(m.end_of_track as u64));
365            o.insert("end_location".into(), loc_to_json(&m.end_location));
366            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
367            o
368        }
369        ControlMessage::FetchError(m) => {
370            let mut o = Map::new();
371            o.insert("request_id".into(), vi(m.request_id.into_inner()));
372            o.insert("error_code".into(), vi(m.error_code.into_inner()));
373            o.insert(
374                "reason_phrase".into(),
375                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
376            );
377            o
378        }
379        ControlMessage::FetchCancel(m) => {
380            let mut o = Map::new();
381            o.insert("request_id".into(), vi(m.request_id.into_inner()));
382            o
383        }
384        ControlMessage::Publish(m) => {
385            let mut o = Map::new();
386            o.insert("request_id".into(), vi(m.request_id.into_inner()));
387            o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
388            o.insert(
389                "track_name".into(),
390                Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
391            );
392            o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
393            o.insert("group_order".into(), vi(m.group_order as u64));
394            o.insert("content_exists".into(), vi(m.content_exists as u64));
395            if let Some(loc) = &m.largest_location {
396                o.insert("largest_location".into(), loc_to_json(loc));
397            }
398            o.insert("forward".into(), vi(m.forward as u64));
399            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
400            o
401        }
402        ControlMessage::PublishOk(m) => {
403            let mut o = Map::new();
404            o.insert("request_id".into(), vi(m.request_id.into_inner()));
405            o.insert("forward".into(), vi(m.forward as u64));
406            o.insert("subscriber_priority".into(), vi(m.subscriber_priority as u64));
407            o.insert("group_order".into(), vi(m.group_order as u64));
408            o.insert("filter_type".into(), vi(m.filter_type as u64));
409            if let Some(sg) = &m.start_group {
410                o.insert("start_group".into(), vi(sg.into_inner()));
411            }
412            if let Some(so) = &m.start_object {
413                o.insert("start_object".into(), vi(so.into_inner()));
414            }
415            if let Some(eg) = &m.end_group {
416                o.insert("end_group".into(), vi(eg.into_inner()));
417            }
418            o.insert("parameters".into(), kvp_to_json_msg(&m.parameters));
419            o
420        }
421        ControlMessage::PublishError(m) => {
422            let mut o = Map::new();
423            o.insert("request_id".into(), vi(m.request_id.into_inner()));
424            o.insert("error_code".into(), vi(m.error_code.into_inner()));
425            o.insert(
426                "reason_phrase".into(),
427                Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
428            );
429            o
430        }
431    };
432    obj
433}