1use crate::draft15::message::ControlMessage;
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 d15_setup_param_name(key: u64) -> Option<&'static str> {
18 match key {
19 0x01 => Some("path"),
20 0x02 => Some("max_request_id"),
21 0x03 => Some("authorization_token"),
22 0x04 => Some("max_auth_token_cache_size"),
23 0x05 => Some("authority"),
24 0x07 => Some("moqt_implementation"),
25 _ => None,
26 }
27}
28
29fn d15_msg_param_name(key: u64) -> Option<&'static str> {
30 match key {
31 0x02 => Some("delivery_timeout"),
32 0x03 => Some("authorization_token"),
33 0x04 => Some("max_cache_duration"),
34 0x08 => Some("expires"),
35 0x09 => Some("largest_object"),
36 0x0e => Some("publisher_priority"),
37 0x10 => Some("forward"),
38 0x20 => Some("subscriber_priority"),
39 0x21 => Some("subscription_filter"),
40 0x22 => Some("group_order"),
41 0x30 => Some("dynamic_groups"),
42 0x32 => Some("new_group_request"),
43 _ => None,
44 }
45}
46
47fn decode_subscription_filter(bytes: &[u8]) -> Value {
71 let mut buf = bytes;
72 let Ok(filter_type) = VarInt::decode(&mut buf) else {
73 return Value::Bytes(bytes.to_vec());
74 };
75 let filter_type = filter_type.into_inner();
76 let mut obj = Map::new();
77 obj.insert("filter_type".into(), vi(filter_type));
78 match filter_type {
79 3 => {
80 let Ok(start_group) = VarInt::decode(&mut buf) else {
82 return Value::Bytes(bytes.to_vec());
83 };
84 let start_group = start_group.into_inner();
85 let Ok(start_object) = VarInt::decode(&mut buf) else {
86 return Value::Bytes(bytes.to_vec());
87 };
88 let start_object = start_object.into_inner();
89 obj.insert("start_group".into(), vi(start_group));
90 obj.insert("start_object".into(), vi(start_object));
91 }
92 4 => {
93 let Ok(start_group) = VarInt::decode(&mut buf) else {
95 return Value::Bytes(bytes.to_vec());
96 };
97 let start_group = start_group.into_inner();
98 let Ok(start_object) = VarInt::decode(&mut buf) else {
99 return Value::Bytes(bytes.to_vec());
100 };
101 let start_object = start_object.into_inner();
102 let Ok(end_group) = VarInt::decode(&mut buf) else {
103 return Value::Bytes(bytes.to_vec());
104 };
105 let end_group = end_group.into_inner();
106 obj.insert("start_group".into(), vi(start_group));
107 obj.insert("start_object".into(), vi(start_object));
108 obj.insert("end_group".into(), vi(end_group));
109 }
110 _ => {
111 }
113 }
114 Value::Map(obj)
115}
116
117fn decode_largest_object(bytes: &[u8]) -> Value {
143 let mut buf = bytes;
144 let Ok(group) = VarInt::decode(&mut buf) else {
145 return Value::Bytes(bytes.to_vec());
146 };
147 let Ok(object) = VarInt::decode(&mut buf) else {
148 return Value::Bytes(bytes.to_vec());
149 };
150 let mut obj = Map::new();
151 obj.insert("group".into(), vi(group.into_inner()));
152 obj.insert("object".into(), vi(object.into_inner()));
153 Value::Map(obj)
154}
155
156fn auth_token_to_json_d15(bytes: &[u8]) -> Value {
158 let mut buf = bytes;
159 let alias_type = match VarInt::decode(&mut buf) {
160 Ok(v) => v,
161 Err(_) => return Value::Bytes(bytes.to_vec()),
162 };
163 let at = alias_type.into_inner();
164 let mut o = Map::new();
165 o.insert("alias_type".into(), vi(at));
166 match at {
167 0 | 2 => {
168 if let Ok(ta) = VarInt::decode(&mut buf) {
169 o.insert("token_alias".into(), vi(ta.into_inner()));
170 }
171 }
172 1 => {
173 if let Ok(ta) = VarInt::decode(&mut buf) {
174 o.insert("token_alias".into(), vi(ta.into_inner()));
175 }
176 if let Ok(tt) = VarInt::decode(&mut buf) {
177 o.insert("token_type".into(), vi(tt.into_inner()));
178 }
179 o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
180 }
181 _ => {
182 if let Ok(tt) = VarInt::decode(&mut buf) {
183 o.insert("token_type".into(), vi(tt.into_inner()));
184 }
185 o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
186 }
187 }
188 Value::Map(o)
189}
190
191fn kvp_to_json_d15_inner(
192 params: &[KeyValuePair],
193 name_fn: fn(u64) -> Option<&'static str>,
194) -> Value {
195 crate::fields::kvp_entries(params, |key, value| {
196 let Some(name) = name_fn(key) else {
197 return (None, None);
198 };
199 let rendered = match (value, key) {
200 (KvpValue::Bytes(b), 0x21) => decode_subscription_filter(b),
201 (KvpValue::Bytes(b), 0x09) => decode_largest_object(b),
202 (KvpValue::Bytes(b), _) if name == "authorization_token" => auth_token_to_json_d15(b),
203 (KvpValue::Varint(v), _) => vi(v.into_inner()),
204 (KvpValue::Bytes(b), _) => Value::Text(String::from_utf8_lossy(b).into_owned()),
205 };
206 (Some(name), Some(rendered))
207 })
208}
209
210fn kvp_to_json_d15(params: &[KeyValuePair]) -> Value {
211 kvp_to_json_d15_inner(params, d15_msg_param_name)
212}
213
214pub(crate) fn kvp_to_json_d15_setup(params: &[KeyValuePair]) -> Value {
215 kvp_to_json_d15_inner(params, d15_setup_param_name)
216}
217
218pub fn message_fields(msg: &ControlMessage) -> Map {
224 let obj = match msg {
225 ControlMessage::ClientSetup(m) => {
226 let mut o = Map::new();
227 o.insert("parameters".into(), kvp_to_json_d15_setup(&m.parameters));
228 o
229 }
230 ControlMessage::ServerSetup(m) => {
231 let mut o = Map::new();
232 o.insert("parameters".into(), kvp_to_json_d15_setup(&m.parameters));
233 o
234 }
235 ControlMessage::GoAway(m) => {
236 let mut o = Map::new();
237 o.insert(
238 "new_session_uri".into(),
239 Value::Text(String::from_utf8_lossy(&m.new_session_uri).into_owned()),
240 );
241 o
242 }
243 ControlMessage::MaxRequestId(m) => {
244 let mut o = Map::new();
245 o.insert("max_request_id".into(), vi(m.request_id.into_inner()));
246 o
247 }
248 ControlMessage::RequestsBlocked(m) => {
249 let mut o = Map::new();
250 o.insert("maximum_request_id".into(), vi(m.maximum_request_id.into_inner()));
251 o
252 }
253 ControlMessage::RequestOk(m) => {
254 let mut o = Map::new();
255 o.insert("request_id".into(), vi(m.request_id.into_inner()));
256 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
257 o
258 }
259 ControlMessage::RequestError(m) => {
260 let mut o = Map::new();
261 o.insert("request_id".into(), vi(m.request_id.into_inner()));
262 o.insert("error_code".into(), vi(m.error_code.into_inner()));
263 o.insert(
264 "reason_phrase".into(),
265 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
266 );
267 o
268 }
269 ControlMessage::Subscribe(m) => {
270 let mut o = Map::new();
271 o.insert("request_id".into(), vi(m.request_id.into_inner()));
272 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
273 o.insert(
274 "track_name".into(),
275 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
276 );
277 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
278 o
279 }
280 ControlMessage::SubscribeOk(m) => {
281 let mut o = Map::new();
282 o.insert("request_id".into(), vi(m.request_id.into_inner()));
283 o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
284 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
285 o
286 }
287 ControlMessage::SubscribeUpdate(m) => {
288 let mut o = Map::new();
289 o.insert("request_id".into(), vi(m.request_id.into_inner()));
290 o.insert("subscription_request_id".into(), vi(m.subscription_request_id.into_inner()));
291 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
292 o
293 }
294 ControlMessage::Unsubscribe(m) => {
295 let mut o = Map::new();
296 o.insert("request_id".into(), vi(m.request_id.into_inner()));
297 o
298 }
299 ControlMessage::Publish(m) => {
300 let mut o = Map::new();
301 o.insert("request_id".into(), vi(m.request_id.into_inner()));
302 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
303 o.insert(
304 "track_name".into(),
305 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
306 );
307 o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
308 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
309 o
310 }
311 ControlMessage::PublishOk(m) => {
312 let mut o = Map::new();
313 o.insert("request_id".into(), vi(m.request_id.into_inner()));
314 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
315 o
316 }
317 ControlMessage::PublishDone(m) => {
318 let mut o = Map::new();
319 o.insert("request_id".into(), vi(m.request_id.into_inner()));
320 o.insert("status_code".into(), vi(m.status_code.into_inner()));
321 o.insert("stream_count".into(), vi(m.stream_count.into_inner()));
322 o.insert(
323 "reason_phrase".into(),
324 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
325 );
326 o
327 }
328 ControlMessage::PublishNamespace(m) => {
329 let mut o = Map::new();
330 o.insert("request_id".into(), vi(m.request_id.into_inner()));
331 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
332 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
333 o
334 }
335 ControlMessage::PublishNamespaceDone(m) => {
336 let mut o = Map::new();
337 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
338 o
339 }
340 ControlMessage::PublishNamespaceCancel(m) => {
341 let mut o = Map::new();
342 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
343 o.insert("error_code".into(), vi(m.error_code.into_inner()));
344 o.insert(
345 "reason_phrase".into(),
346 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
347 );
348 o
349 }
350 ControlMessage::SubscribeNamespace(m) => {
351 let mut o = Map::new();
352 o.insert("request_id".into(), vi(m.request_id.into_inner()));
353 o.insert("namespace_prefix".into(), ns_to_json(&m.namespace_prefix));
354 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
355 o
356 }
357 ControlMessage::UnsubscribeNamespace(m) => {
358 let mut o = Map::new();
359 o.insert("request_id".into(), vi(m.request_id.into_inner()));
360 o
361 }
362 ControlMessage::TrackStatus(m) => {
363 let mut o = Map::new();
364 o.insert("request_id".into(), vi(m.request_id.into_inner()));
365 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
366 o.insert(
367 "track_name".into(),
368 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
369 );
370 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
371 o
372 }
373 ControlMessage::Fetch(m) => {
374 let mut o = Map::new();
375 o.insert("request_id".into(), vi(m.request_id.into_inner()));
376 o.insert("fetch_type".into(), vi(m.fetch_type as u64));
377 match &m.fetch_payload {
378 crate::draft15::message::FetchPayload::Standalone {
379 track_namespace,
380 track_name,
381 start_group,
382 start_object,
383 end_group,
384 end_object,
385 } => {
386 o.insert("track_namespace".into(), ns_to_json(track_namespace));
387 o.insert(
388 "track_name".into(),
389 Value::Text(String::from_utf8_lossy(track_name).into_owned()),
390 );
391 o.insert("start_group".into(), vi(start_group.into_inner()));
392 o.insert("start_object".into(), vi(start_object.into_inner()));
393 o.insert("end_group".into(), vi(end_group.into_inner()));
394 o.insert("end_object".into(), vi(end_object.into_inner()));
395 }
396 crate::draft15::message::FetchPayload::Joining {
397 joining_request_id,
398 joining_start,
399 } => {
400 o.insert("joining_request_id".into(), vi(joining_request_id.into_inner()));
401 o.insert("joining_start".into(), vi(joining_start.into_inner()));
402 }
403 }
404 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
405 o
406 }
407 ControlMessage::FetchOk(m) => {
408 let mut o = Map::new();
409 o.insert("request_id".into(), vi(m.request_id.into_inner()));
410 o.insert("end_of_track".into(), vi(m.end_of_track as u64));
411 o.insert("end_group".into(), vi(m.end_group.into_inner()));
412 o.insert("end_object".into(), vi(m.end_object.into_inner()));
413 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
414 o
415 }
416 ControlMessage::FetchCancel(m) => {
417 let mut o = Map::new();
418 o.insert("request_id".into(), vi(m.request_id.into_inner()));
419 o
420 }
421 };
422 obj
423}