1pub use crate::error::{
20 CodecError, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH, MAX_NAMESPACE_TUPLE_SIZE,
21 MAX_REASON_PHRASE_LENGTH,
22};
23use crate::kvp::{KeyValuePair, KvpValue};
24use crate::types::*;
25use crate::varint::VarInt;
26use bytes::{Buf, BufMut};
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34enum ParamEncoding {
35 Varint,
37 Uint8,
39 LengthPrefixed,
41}
42
43fn param_encoding(key: u64) -> Option<ParamEncoding> {
44 match key {
45 0x02 | 0x04 | 0x06 | 0x08 | 0x0A | 0x32 => Some(ParamEncoding::Varint),
52 0x10 | 0x20 | 0x22 => Some(ParamEncoding::Uint8),
54 0x03 | 0x09 | 0x21 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x34 => {
62 Some(ParamEncoding::LengthPrefixed)
63 }
64 _ => None,
65 }
66}
67
68fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
70 let count = VarInt::decode(buf)?.into_inner() as usize;
71 let mut params = Vec::with_capacity(count);
72 let mut prev_key: u64 = 0;
73
74 for _ in 0..count {
75 let delta = VarInt::decode(buf)?.into_inner();
76 let abs_key = prev_key + delta;
77 prev_key = abs_key;
78
79 let encoding = param_encoding(abs_key).ok_or(CodecError::InvalidField)?;
80
81 let value = match encoding {
82 ParamEncoding::Varint => {
83 let v = VarInt::decode(buf)?;
84 KvpValue::Varint(v)
85 }
86 ParamEncoding::Uint8 => {
87 if buf.remaining() < 1 {
88 return Err(CodecError::UnexpectedEnd);
89 }
90 let byte = buf.get_u8();
91 KvpValue::Varint(VarInt::from_u64(byte as u64).unwrap())
92 }
93 ParamEncoding::LengthPrefixed => {
94 let len = VarInt::decode(buf)?.into_inner() as usize;
95 let data = read_bytes(buf, len)?;
96 KvpValue::Bytes(data)
97 }
98 };
99
100 params.push(KeyValuePair { key: VarInt::from_u64(abs_key).unwrap(), value });
101 }
102 Ok(params)
103}
104
105fn encode_parameters(params: &[KeyValuePair], buf: &mut impl BufMut) {
107 VarInt::from_usize(params.len()).encode(buf);
108 let mut prev_key: u64 = 0;
109
110 for p in params {
111 let abs_key = p.key.into_inner();
112 let delta = abs_key - prev_key;
113 prev_key = abs_key;
114 VarInt::from_u64(delta).unwrap().encode(buf);
115
116 let encoding = param_encoding(abs_key);
117 match (&p.value, encoding) {
118 (KvpValue::Varint(v), Some(ParamEncoding::Varint)) => {
119 v.encode(buf);
120 }
121 (KvpValue::Varint(v), Some(ParamEncoding::Uint8)) => {
122 buf.put_u8(v.into_inner() as u8);
123 }
124 (KvpValue::Bytes(b), Some(ParamEncoding::LengthPrefixed)) => {
125 VarInt::from_usize(b.len()).encode(buf);
126 buf.put_slice(b);
127 }
128 _ => {
129 match &p.value {
131 KvpValue::Varint(v) => v.encode(buf),
132 KvpValue::Bytes(b) => {
133 VarInt::from_usize(b.len()).encode(buf);
134 buf.put_slice(b);
135 }
136 }
137 }
138 }
139 }
140}
141
142fn decode_kvp_delta(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
145 let mut pairs = Vec::new();
146 let mut prev_key: u64 = 0;
147
148 while buf.has_remaining() {
149 let delta = VarInt::decode(buf)?.into_inner();
150 let abs_key = prev_key + delta;
151 prev_key = abs_key;
152
153 let value = if abs_key % 2 == 0 {
154 let v = VarInt::decode(buf)?;
155 KvpValue::Varint(v)
156 } else {
157 let len = VarInt::decode(buf)?.into_inner() as usize;
158 let data = read_bytes(buf, len)?;
159 KvpValue::Bytes(data)
160 };
161
162 pairs.push(KeyValuePair { key: VarInt::from_u64(abs_key).unwrap(), value });
163 }
164 Ok(pairs)
165}
166
167fn encode_kvp_delta(pairs: &[KeyValuePair], buf: &mut impl BufMut) {
169 let mut prev_key: u64 = 0;
170 for p in pairs {
171 let abs_key = p.key.into_inner();
172 let delta = abs_key - prev_key;
173 prev_key = abs_key;
174 VarInt::from_u64(delta).unwrap().encode(buf);
175 match &p.value {
176 KvpValue::Varint(v) => v.encode(buf),
177 KvpValue::Bytes(b) => {
178 VarInt::from_usize(b.len()).encode(buf);
179 buf.put_slice(b);
180 }
181 }
182 }
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
190#[repr(u64)]
191pub enum MessageType {
192 RequestUpdate = 0x02,
193 Subscribe = 0x03,
194 SubscribeOk = 0x04,
195 RequestError = 0x05,
196 PublishNamespace = 0x06,
197 RequestOk = 0x07,
199 Namespace = 0x08,
200 PublishDone = 0x0B,
201 TrackStatus = 0x0D,
202 NamespaceDone = 0x0E,
203 PublishSkipped = 0x0F,
204 GoAway = 0x10,
205 Fetch = 0x16,
206 FetchOk = 0x18,
207 Publish = 0x1D,
208 SubscribeNamespace = 0x50,
210 SubscribeTracks = 0x51,
212 Setup = 0x2F00,
213}
214
215impl MessageType {
216 pub fn from_id(id: u64) -> Option<Self> {
217 match id {
218 0x02 => Some(MessageType::RequestUpdate),
219 0x03 => Some(MessageType::Subscribe),
220 0x04 => Some(MessageType::SubscribeOk),
221 0x05 => Some(MessageType::RequestError),
222 0x06 => Some(MessageType::PublishNamespace),
223 0x07 => Some(MessageType::RequestOk),
224 0x08 => Some(MessageType::Namespace),
225 0x0B => Some(MessageType::PublishDone),
226 0x0D => Some(MessageType::TrackStatus),
227 0x0E => Some(MessageType::NamespaceDone),
228 0x0F => Some(MessageType::PublishSkipped),
229 0x10 => Some(MessageType::GoAway),
230 0x16 => Some(MessageType::Fetch),
231 0x18 => Some(MessageType::FetchOk),
232 0x1D => Some(MessageType::Publish),
233 0x50 => Some(MessageType::SubscribeNamespace),
234 0x51 => Some(MessageType::SubscribeTracks),
235 0x2F00 => Some(MessageType::Setup),
236 _ => None,
237 }
238 }
239
240 pub fn id(&self) -> u64 {
241 *self as u64
242 }
243}
244
245#[derive(Debug, Clone, PartialEq, Eq)]
251pub struct Setup {
252 pub options: Vec<KeyValuePair>,
253}
254
255#[derive(Debug, Clone, PartialEq, Eq)]
258pub struct GoAway {
259 pub new_session_uri: Vec<u8>,
260 pub timeout: VarInt,
261}
262
263#[derive(Debug, Clone, PartialEq, Eq)]
274pub struct RequestOk {
275 pub parameters: Vec<KeyValuePair>,
276 pub track_properties: Vec<KeyValuePair>,
277}
278
279#[derive(Debug, Clone, PartialEq, Eq)]
281pub struct Redirect {
282 pub connect_uri: Vec<u8>,
283 pub track_namespace: TrackNamespace,
284 pub track_name: Vec<u8>,
285}
286
287#[derive(Debug, Clone, PartialEq, Eq)]
290pub struct RequestError {
291 pub error_code: VarInt,
292 pub retry_interval: VarInt,
293 pub reason_phrase: Vec<u8>,
294 pub redirect: Option<Redirect>,
295}
296
297pub mod request_error_codes {
302 pub const UNSUPPORTED_EXTENSION: u64 = 0x33;
304 pub const REDIRECT: u64 = 0x34;
306 pub const CONFLICTING_FILTERS: u64 = 0x35;
309 pub const INVALID_FILTER: u64 = 0x36;
312}
313
314#[derive(Debug, Clone, PartialEq, Eq)]
319pub struct Subscribe {
320 pub request_id: VarInt,
321 pub track_namespace: TrackNamespace,
322 pub track_name: Vec<u8>,
323 pub parameters: Vec<KeyValuePair>,
324}
325
326#[derive(Debug, Clone, PartialEq, Eq)]
328pub struct SubscribeOk {
329 pub track_alias: VarInt,
330 pub parameters: Vec<KeyValuePair>,
331 pub track_properties: Vec<KeyValuePair>,
332}
333
334#[derive(Debug, Clone, PartialEq, Eq)]
335pub struct RequestUpdate {
336 pub request_id: VarInt,
337 pub parameters: Vec<KeyValuePair>,
338}
339
340#[derive(Debug, Clone, PartialEq, Eq)]
345pub struct Publish {
346 pub request_id: VarInt,
347 pub track_namespace: TrackNamespace,
348 pub track_name: Vec<u8>,
349 pub track_alias: VarInt,
350 pub parameters: Vec<KeyValuePair>,
351 pub track_properties: Vec<KeyValuePair>,
352}
353
354#[derive(Debug, Clone, PartialEq, Eq)]
356pub struct PublishDone {
357 pub status_code: VarInt,
358 pub stream_count: VarInt,
359 pub reason_phrase: Vec<u8>,
360}
361
362pub mod publish_done_codes {
364 pub const TOO_FAR_BEHIND: u64 = 0x05;
366 pub const EXPIRED: u64 = 0x06;
368}
369
370#[derive(Debug, Clone, PartialEq, Eq)]
375pub struct PublishNamespace {
376 pub request_id: VarInt,
377 pub track_namespace: TrackNamespace,
378 pub parameters: Vec<KeyValuePair>,
379}
380
381#[derive(Debug, Clone, PartialEq, Eq)]
386pub struct Namespace {
387 pub namespace_suffix: TrackNamespace,
388}
389
390#[derive(Debug, Clone, PartialEq, Eq)]
391pub struct NamespaceDone {
392 pub namespace_suffix: TrackNamespace,
393}
394
395#[derive(Debug, Clone, PartialEq, Eq)]
404pub struct SubscribeNamespace {
405 pub request_id: VarInt,
406 pub namespace_prefix: TrackNamespace,
407 pub parameters: Vec<KeyValuePair>,
408}
409
410#[derive(Debug, Clone, PartialEq, Eq)]
414pub struct SubscribeTracks {
415 pub request_id: VarInt,
416 pub namespace_prefix: TrackNamespace,
417 pub parameters: Vec<KeyValuePair>,
418}
419
420#[derive(Debug, Clone, PartialEq, Eq)]
425pub struct TrackStatus {
426 pub request_id: VarInt,
427 pub track_namespace: TrackNamespace,
428 pub track_name: Vec<u8>,
429 pub parameters: Vec<KeyValuePair>,
430}
431
432#[derive(Debug, Clone, Copy, PartialEq, Eq)]
437#[repr(u64)]
438pub enum FetchType {
439 Standalone = 1,
440 RelativeJoining = 2,
441 AbsoluteJoining = 3,
442}
443
444impl FetchType {
445 pub fn from_u64(v: u64) -> Option<Self> {
446 match v {
447 1 => Some(FetchType::Standalone),
448 2 => Some(FetchType::RelativeJoining),
449 3 => Some(FetchType::AbsoluteJoining),
450 _ => None,
451 }
452 }
453}
454
455#[derive(Debug, Clone, PartialEq, Eq)]
456pub struct Fetch {
457 pub request_id: VarInt,
458 pub fetch_type: FetchType,
459 pub fetch_payload: FetchPayload,
460 pub parameters: Vec<KeyValuePair>,
461}
462
463#[derive(Debug, Clone, PartialEq, Eq)]
464pub enum FetchPayload {
465 Standalone {
466 track_namespace: TrackNamespace,
467 track_name: Vec<u8>,
468 start_group: VarInt,
469 start_object: VarInt,
470 end_group: VarInt,
471 end_object: VarInt,
472 },
473 Joining {
474 joining_request_id: VarInt,
475 joining_start: VarInt,
476 },
477}
478
479#[derive(Debug, Clone, PartialEq, Eq)]
481pub struct FetchOk {
482 pub end_of_track: u8,
483 pub end_group: VarInt,
484 pub end_object: VarInt,
485 pub parameters: Vec<KeyValuePair>,
486 pub track_properties: Vec<KeyValuePair>,
487}
488
489#[derive(Debug, Clone, PartialEq, Eq)]
496pub struct PublishSkipped {
497 pub namespace_suffix: TrackNamespace,
498 pub track_name: Vec<u8>,
499}
500
501#[derive(Debug, Clone, PartialEq, Eq)]
506pub enum ControlMessage {
507 Setup(Setup),
508 GoAway(GoAway),
509 RequestOk(RequestOk),
510 RequestError(RequestError),
511 Subscribe(Subscribe),
512 SubscribeOk(SubscribeOk),
513 RequestUpdate(RequestUpdate),
514 Publish(Publish),
515 PublishDone(PublishDone),
516 PublishNamespace(PublishNamespace),
517 Namespace(Namespace),
518 NamespaceDone(NamespaceDone),
519 SubscribeNamespace(SubscribeNamespace),
520 SubscribeTracks(SubscribeTracks),
521 TrackStatus(TrackStatus),
522 Fetch(Fetch),
523 FetchOk(FetchOk),
524 PublishSkipped(PublishSkipped),
525}
526
527impl ControlMessage {
528 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
529 let mut payload = Vec::with_capacity(256);
530 self.encode_payload(&mut payload)?;
531
532 if payload.len() > MAX_MESSAGE_LENGTH {
533 return Err(CodecError::MessageTooLong(payload.len()));
534 }
535
536 let msg_type = self.message_type();
537 VarInt::from_usize(msg_type.id() as usize).encode(buf);
538 buf.put_u16(payload.len() as u16);
540 buf.put_slice(&payload);
541 Ok(())
542 }
543
544 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
545 let type_id = VarInt::decode(buf)?.into_inner();
546 let msg_type =
547 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
548 if buf.remaining() < 2 {
550 return Err(CodecError::UnexpectedEnd);
551 }
552 let payload_len = buf.get_u16() as usize;
553 if buf.remaining() < payload_len {
554 return Err(CodecError::UnexpectedEnd);
555 }
556 let payload_bytes = buf.copy_to_bytes(payload_len);
557 let mut payload = &payload_bytes[..];
558 Self::decode_payload(msg_type, &mut payload)
559 }
560
561 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
562 match self {
563 ControlMessage::Setup(m) => {
564 encode_kvp_delta(&m.options, buf);
565 }
566 ControlMessage::GoAway(m) => {
567 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
568 return Err(CodecError::GoAwayUriTooLong);
569 }
570 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
571 buf.put_slice(&m.new_session_uri);
572 m.timeout.encode(buf);
573 }
574 ControlMessage::RequestOk(m) => {
575 encode_parameters(&m.parameters, buf);
576 encode_kvp_delta(&m.track_properties, buf);
577 }
578 ControlMessage::RequestError(m) => {
579 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
580 return Err(CodecError::ReasonPhraseTooLong);
581 }
582 m.error_code.encode(buf);
583 m.retry_interval.encode(buf);
584 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
585 buf.put_slice(&m.reason_phrase);
586 if let Some(r) = &m.redirect {
587 VarInt::from_usize(r.connect_uri.len()).encode(buf);
588 buf.put_slice(&r.connect_uri);
589 r.track_namespace.encode(buf);
590 VarInt::from_usize(r.track_name.len()).encode(buf);
591 buf.put_slice(&r.track_name);
592 }
593 }
594 ControlMessage::Subscribe(m) => {
595 m.request_id.encode(buf);
596 m.track_namespace.encode(buf);
597 VarInt::from_usize(m.track_name.len()).encode(buf);
598 buf.put_slice(&m.track_name);
599 encode_parameters(&m.parameters, buf);
600 }
601 ControlMessage::SubscribeOk(m) => {
602 m.track_alias.encode(buf);
603 encode_parameters(&m.parameters, buf);
604 encode_kvp_delta(&m.track_properties, buf);
605 }
606 ControlMessage::RequestUpdate(m) => {
607 m.request_id.encode(buf);
608 encode_parameters(&m.parameters, buf);
609 }
610 ControlMessage::Publish(m) => {
611 m.request_id.encode(buf);
612 m.track_namespace.encode(buf);
613 VarInt::from_usize(m.track_name.len()).encode(buf);
614 buf.put_slice(&m.track_name);
615 m.track_alias.encode(buf);
616 encode_parameters(&m.parameters, buf);
617 encode_kvp_delta(&m.track_properties, buf);
618 }
619 ControlMessage::PublishDone(m) => {
620 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
621 return Err(CodecError::ReasonPhraseTooLong);
622 }
623 m.status_code.encode(buf);
624 m.stream_count.encode(buf);
625 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
626 buf.put_slice(&m.reason_phrase);
627 }
628 ControlMessage::PublishNamespace(m) => {
629 m.request_id.encode(buf);
630 m.track_namespace.encode(buf);
631 encode_parameters(&m.parameters, buf);
632 }
633 ControlMessage::Namespace(m) => {
634 m.namespace_suffix.encode(buf);
635 }
636 ControlMessage::NamespaceDone(m) => {
637 m.namespace_suffix.encode(buf);
638 }
639 ControlMessage::SubscribeNamespace(m) => {
640 m.request_id.encode(buf);
641 m.namespace_prefix.encode(buf);
642 encode_parameters(&m.parameters, buf);
643 }
644 ControlMessage::SubscribeTracks(m) => {
645 m.request_id.encode(buf);
646 m.namespace_prefix.encode(buf);
647 encode_parameters(&m.parameters, buf);
648 }
649 ControlMessage::TrackStatus(m) => {
650 m.request_id.encode(buf);
651 m.track_namespace.encode(buf);
652 VarInt::from_usize(m.track_name.len()).encode(buf);
653 buf.put_slice(&m.track_name);
654 encode_parameters(&m.parameters, buf);
655 }
656 ControlMessage::Fetch(m) => {
657 m.request_id.encode(buf);
658 VarInt::from_usize(m.fetch_type as usize).encode(buf);
659 match &m.fetch_payload {
660 FetchPayload::Standalone {
661 track_namespace,
662 track_name,
663 start_group,
664 start_object,
665 end_group,
666 end_object,
667 } => {
668 track_namespace.encode(buf);
669 VarInt::from_usize(track_name.len()).encode(buf);
670 buf.put_slice(track_name);
671 start_group.encode(buf);
672 start_object.encode(buf);
673 end_group.encode(buf);
674 end_object.encode(buf);
675 }
676 FetchPayload::Joining { joining_request_id, joining_start } => {
677 joining_request_id.encode(buf);
678 joining_start.encode(buf);
679 }
680 }
681 encode_parameters(&m.parameters, buf);
682 }
683 ControlMessage::FetchOk(m) => {
684 buf.put_u8(m.end_of_track);
685 m.end_group.encode(buf);
686 m.end_object.encode(buf);
687 encode_parameters(&m.parameters, buf);
688 encode_kvp_delta(&m.track_properties, buf);
689 }
690 ControlMessage::PublishSkipped(m) => {
691 m.namespace_suffix.encode(buf);
692 VarInt::from_usize(m.track_name.len()).encode(buf);
693 buf.put_slice(&m.track_name);
694 }
695 }
696 Ok(())
697 }
698
699 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
700 match msg_type {
701 MessageType::Setup => {
702 let options = decode_kvp_delta(buf)?;
703 Ok(ControlMessage::Setup(Setup { options }))
704 }
705 MessageType::GoAway => {
706 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
707 let uri = read_bytes(buf, uri_len)?;
708 let timeout = VarInt::decode(buf)?;
709 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri, timeout }))
710 }
711 MessageType::RequestOk => {
712 let parameters = decode_parameters(buf)?;
713 let track_properties = decode_kvp_delta(buf)?;
714 Ok(ControlMessage::RequestOk(RequestOk { parameters, track_properties }))
715 }
716 MessageType::RequestError => {
717 let error_code = VarInt::decode(buf)?;
718 let retry_interval = VarInt::decode(buf)?;
719 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
720 let reason_phrase = read_bytes(buf, reason_len)?;
721 let redirect = if error_code.into_inner() == request_error_codes::REDIRECT {
722 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
723 let connect_uri = read_bytes(buf, uri_len)?;
724 let track_namespace = TrackNamespace::decode_allow_empty(buf)?;
725 let name_len = VarInt::decode(buf)?.into_inner() as usize;
726 let track_name = read_bytes(buf, name_len)?;
727 Some(Redirect { connect_uri, track_namespace, track_name })
728 } else {
729 None
730 };
731 Ok(ControlMessage::RequestError(RequestError {
732 error_code,
733 retry_interval,
734 reason_phrase,
735 redirect,
736 }))
737 }
738 MessageType::Subscribe => {
739 let request_id = VarInt::decode(buf)?;
740 let track_namespace = TrackNamespace::decode(buf)?;
741 let tn_len = VarInt::decode(buf)?.into_inner() as usize;
742 let track_name = read_bytes(buf, tn_len)?;
743 let parameters = decode_parameters(buf)?;
744 Ok(ControlMessage::Subscribe(Subscribe {
745 request_id,
746 track_namespace,
747 track_name,
748 parameters,
749 }))
750 }
751 MessageType::SubscribeOk => {
752 let track_alias = VarInt::decode(buf)?;
753 let parameters = decode_parameters(buf)?;
754 let track_properties = decode_kvp_delta(buf)?;
755 Ok(ControlMessage::SubscribeOk(SubscribeOk {
756 track_alias,
757 parameters,
758 track_properties,
759 }))
760 }
761 MessageType::RequestUpdate => {
762 let request_id = VarInt::decode(buf)?;
763 let parameters = decode_parameters(buf)?;
764 Ok(ControlMessage::RequestUpdate(RequestUpdate { request_id, parameters }))
765 }
766 MessageType::Publish => {
767 let request_id = VarInt::decode(buf)?;
768 let track_namespace = TrackNamespace::decode(buf)?;
769 let tn_len = VarInt::decode(buf)?.into_inner() as usize;
770 let track_name = read_bytes(buf, tn_len)?;
771 let track_alias = VarInt::decode(buf)?;
772 let parameters = decode_parameters(buf)?;
773 let track_properties = decode_kvp_delta(buf)?;
774 Ok(ControlMessage::Publish(Publish {
775 request_id,
776 track_namespace,
777 track_name,
778 track_alias,
779 parameters,
780 track_properties,
781 }))
782 }
783 MessageType::PublishDone => {
784 let status_code = VarInt::decode(buf)?;
785 let stream_count = VarInt::decode(buf)?;
786 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
787 let reason_phrase = read_bytes(buf, reason_len)?;
788 Ok(ControlMessage::PublishDone(PublishDone {
789 status_code,
790 stream_count,
791 reason_phrase,
792 }))
793 }
794 MessageType::PublishNamespace => {
795 let request_id = VarInt::decode(buf)?;
796 let track_namespace = TrackNamespace::decode(buf)?;
797 let parameters = decode_parameters(buf)?;
798 Ok(ControlMessage::PublishNamespace(PublishNamespace {
799 request_id,
800 track_namespace,
801 parameters,
802 }))
803 }
804 MessageType::Namespace => {
805 let namespace_suffix = TrackNamespace::decode_allow_empty(buf)?;
806 Ok(ControlMessage::Namespace(Namespace { namespace_suffix }))
807 }
808 MessageType::NamespaceDone => {
809 let namespace_suffix = TrackNamespace::decode_allow_empty(buf)?;
810 Ok(ControlMessage::NamespaceDone(NamespaceDone { namespace_suffix }))
811 }
812 MessageType::SubscribeNamespace => {
813 let request_id = VarInt::decode(buf)?;
814 let namespace_prefix = TrackNamespace::decode_allow_empty(buf)?;
815 let parameters = decode_parameters(buf)?;
816 Ok(ControlMessage::SubscribeNamespace(SubscribeNamespace {
817 request_id,
818 namespace_prefix,
819 parameters,
820 }))
821 }
822 MessageType::SubscribeTracks => {
823 let request_id = VarInt::decode(buf)?;
824 let namespace_prefix = TrackNamespace::decode_allow_empty(buf)?;
825 let parameters = decode_parameters(buf)?;
826 Ok(ControlMessage::SubscribeTracks(SubscribeTracks {
827 request_id,
828 namespace_prefix,
829 parameters,
830 }))
831 }
832 MessageType::TrackStatus => {
833 let request_id = VarInt::decode(buf)?;
834 let track_namespace = TrackNamespace::decode(buf)?;
835 let tn_len = VarInt::decode(buf)?.into_inner() as usize;
836 let track_name = read_bytes(buf, tn_len)?;
837 let parameters = decode_parameters(buf)?;
838 Ok(ControlMessage::TrackStatus(TrackStatus {
839 request_id,
840 track_namespace,
841 track_name,
842 parameters,
843 }))
844 }
845 MessageType::Fetch => {
846 let request_id = VarInt::decode(buf)?;
847 let fetch_type_val = VarInt::decode(buf)?.into_inner();
848 let fetch_type =
849 FetchType::from_u64(fetch_type_val).ok_or(CodecError::InvalidField)?;
850 let fetch_payload = match fetch_type {
851 FetchType::Standalone => {
852 let track_namespace = TrackNamespace::decode(buf)?;
853 let tn_len = VarInt::decode(buf)?.into_inner() as usize;
854 let track_name = read_bytes(buf, tn_len)?;
855 let start_group = VarInt::decode(buf)?;
856 let start_object = VarInt::decode(buf)?;
857 let end_group = VarInt::decode(buf)?;
858 let end_object = VarInt::decode(buf)?;
859 FetchPayload::Standalone {
860 track_namespace,
861 track_name,
862 start_group,
863 start_object,
864 end_group,
865 end_object,
866 }
867 }
868 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
869 let joining_request_id = VarInt::decode(buf)?;
870 let joining_start = VarInt::decode(buf)?;
871 FetchPayload::Joining { joining_request_id, joining_start }
872 }
873 };
874 let parameters = decode_parameters(buf)?;
875 Ok(ControlMessage::Fetch(Fetch {
876 request_id,
877 fetch_type,
878 fetch_payload,
879 parameters,
880 }))
881 }
882 MessageType::FetchOk => {
883 if buf.remaining() < 1 {
884 return Err(CodecError::UnexpectedEnd);
885 }
886 let end_of_track = buf.get_u8();
887 let end_group = VarInt::decode(buf)?;
888 let end_object = VarInt::decode(buf)?;
889 let parameters = decode_parameters(buf)?;
890 let track_properties = decode_kvp_delta(buf)?;
891 Ok(ControlMessage::FetchOk(FetchOk {
892 end_of_track,
893 end_group,
894 end_object,
895 parameters,
896 track_properties,
897 }))
898 }
899 MessageType::PublishSkipped => {
900 let namespace_suffix = TrackNamespace::decode_allow_empty(buf)?;
901 let tn_len = VarInt::decode(buf)?.into_inner() as usize;
902 let track_name = read_bytes(buf, tn_len)?;
903 Ok(ControlMessage::PublishSkipped(PublishSkipped { namespace_suffix, track_name }))
904 }
905 }
906 }
907
908 pub fn message_type(&self) -> MessageType {
909 match self {
910 ControlMessage::Setup(_) => MessageType::Setup,
911 ControlMessage::GoAway(_) => MessageType::GoAway,
912 ControlMessage::RequestOk(_) => MessageType::RequestOk,
913 ControlMessage::RequestError(_) => MessageType::RequestError,
914 ControlMessage::Subscribe(_) => MessageType::Subscribe,
915 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
916 ControlMessage::RequestUpdate(_) => MessageType::RequestUpdate,
917 ControlMessage::Publish(_) => MessageType::Publish,
918 ControlMessage::PublishDone(_) => MessageType::PublishDone,
919 ControlMessage::PublishNamespace(_) => MessageType::PublishNamespace,
920 ControlMessage::Namespace(_) => MessageType::Namespace,
921 ControlMessage::NamespaceDone(_) => MessageType::NamespaceDone,
922 ControlMessage::SubscribeNamespace(_) => MessageType::SubscribeNamespace,
923 ControlMessage::SubscribeTracks(_) => MessageType::SubscribeTracks,
924 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
925 ControlMessage::Fetch(_) => MessageType::Fetch,
926 ControlMessage::FetchOk(_) => MessageType::FetchOk,
927 ControlMessage::PublishSkipped(_) => MessageType::PublishSkipped,
928 }
929 }
930}