1use crate::auth_token::{AuthorizationToken, AUTH_TOKEN_PARAMETER_D11};
23use crate::error::{
24 CodecError, MAX_FULL_TRACK_NAME_LENGTH, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH,
25 MAX_REASON_PHRASE_LENGTH,
26};
27use crate::kvp::{KeyValuePair, KvpValue};
28use crate::types::{self, *};
29pub use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
30use crate::varint::VarInt;
31use bytes::{Buf, BufMut};
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35#[repr(u64)]
36pub enum MessageType {
37 SubscribeUpdate = 0x02,
39 Subscribe = 0x03,
41 SubscribeOk = 0x04,
43 SubscribeError = 0x05,
45 Announce = 0x06,
47 AnnounceOk = 0x07,
49 AnnounceError = 0x08,
51 Unannounce = 0x09,
53 Unsubscribe = 0x0A,
55 SubscribeDone = 0x0B,
57 AnnounceCancel = 0x0C,
59 TrackStatusRequest = 0x0D,
61 TrackStatus = 0x0E,
63 GoAway = 0x10,
65 SubscribeAnnounces = 0x11,
67 SubscribeAnnouncesOk = 0x12,
69 SubscribeAnnouncesError = 0x13,
71 UnsubscribeAnnounces = 0x14,
73 MaxRequestId = 0x15,
75 Fetch = 0x16,
77 FetchCancel = 0x17,
79 FetchOk = 0x18,
81 FetchError = 0x19,
83 RequestsBlocked = 0x1A,
85 ClientSetup = 0x20,
87 ServerSetup = 0x21,
89}
90
91impl MessageType {
92 pub fn from_id(id: u64) -> Option<Self> {
94 match id {
95 0x02 => Some(MessageType::SubscribeUpdate),
96 0x03 => Some(MessageType::Subscribe),
97 0x04 => Some(MessageType::SubscribeOk),
98 0x05 => Some(MessageType::SubscribeError),
99 0x06 => Some(MessageType::Announce),
100 0x07 => Some(MessageType::AnnounceOk),
101 0x08 => Some(MessageType::AnnounceError),
102 0x09 => Some(MessageType::Unannounce),
103 0x0A => Some(MessageType::Unsubscribe),
104 0x0B => Some(MessageType::SubscribeDone),
105 0x0C => Some(MessageType::AnnounceCancel),
106 0x0D => Some(MessageType::TrackStatusRequest),
107 0x0E => Some(MessageType::TrackStatus),
108 0x10 => Some(MessageType::GoAway),
109 0x11 => Some(MessageType::SubscribeAnnounces),
110 0x12 => Some(MessageType::SubscribeAnnouncesOk),
111 0x13 => Some(MessageType::SubscribeAnnouncesError),
112 0x14 => Some(MessageType::UnsubscribeAnnounces),
113 0x15 => Some(MessageType::MaxRequestId),
114 0x16 => Some(MessageType::Fetch),
115 0x17 => Some(MessageType::FetchCancel),
116 0x18 => Some(MessageType::FetchOk),
117 0x19 => Some(MessageType::FetchError),
118 0x1A => Some(MessageType::RequestsBlocked),
119 0x20 => Some(MessageType::ClientSetup),
120 0x21 => Some(MessageType::ServerSetup),
121 _ => None,
122 }
123 }
124
125 pub fn id(&self) -> u64 {
127 *self as u64
128 }
129
130 pub fn name(&self) -> &'static str {
133 match self {
134 MessageType::SubscribeUpdate => "subscribe_update",
135 MessageType::Subscribe => "subscribe",
136 MessageType::SubscribeOk => "subscribe_ok",
137 MessageType::SubscribeError => "subscribe_error",
138 MessageType::Announce => "announce",
139 MessageType::AnnounceOk => "announce_ok",
140 MessageType::AnnounceError => "announce_error",
141 MessageType::Unannounce => "unannounce",
142 MessageType::Unsubscribe => "unsubscribe",
143 MessageType::SubscribeDone => "subscribe_done",
144 MessageType::AnnounceCancel => "announce_cancel",
145 MessageType::TrackStatusRequest => "track_status_request",
146 MessageType::TrackStatus => "track_status",
147 MessageType::GoAway => "goaway",
148 MessageType::SubscribeAnnounces => "subscribe_announces",
149 MessageType::SubscribeAnnouncesOk => "subscribe_announces_ok",
150 MessageType::SubscribeAnnouncesError => "subscribe_announces_error",
151 MessageType::UnsubscribeAnnounces => "unsubscribe_announces",
152 MessageType::MaxRequestId => "max_request_id",
153 MessageType::Fetch => "fetch",
154 MessageType::FetchCancel => "fetch_cancel",
155 MessageType::FetchOk => "fetch_ok",
156 MessageType::FetchError => "fetch_error",
157 MessageType::RequestsBlocked => "requests_blocked",
158 MessageType::ClientSetup => "client_setup",
159 MessageType::ServerSetup => "server_setup",
160 }
161 }
162}
163
164#[derive(Debug, Clone, PartialEq, Eq)]
170pub struct ClientSetup {
171 pub supported_versions: Vec<VarInt>,
173 pub parameters: Vec<KeyValuePair>,
175}
176
177#[derive(Debug, Clone, PartialEq, Eq)]
179pub struct ServerSetup {
180 pub selected_version: VarInt,
182 pub parameters: Vec<KeyValuePair>,
184}
185
186#[derive(Debug, Clone, PartialEq, Eq)]
188pub struct GoAway {
189 pub new_session_uri: Vec<u8>,
191}
192
193#[derive(Debug, Clone, PartialEq, Eq)]
195pub struct MaxRequestId {
196 pub request_id: VarInt,
198}
199
200#[derive(Debug, Clone, PartialEq, Eq)]
202pub struct RequestsBlocked {
203 pub maximum_request_id: VarInt,
205}
206
207#[derive(Debug, Clone, PartialEq, Eq)]
213pub struct Subscribe {
214 pub request_id: VarInt,
216 pub track_alias: VarInt,
218 pub track_namespace: TrackNamespace,
220 pub track_name: Vec<u8>,
222 pub subscriber_priority: u8,
224 pub group_order: GroupOrder,
226 pub forward: Forward,
228 pub filter_type: VarInt,
230 pub start_group: Option<VarInt>,
232 pub start_object: Option<VarInt>,
234 pub end_group: Option<VarInt>,
236 pub parameters: Vec<KeyValuePair>,
238}
239
240#[derive(Debug, Clone, PartialEq, Eq)]
242pub struct SubscribeOk {
243 pub request_id: VarInt,
245 pub expires: VarInt,
247 pub group_order: GroupOrder,
249 pub content_exists: ContentExists,
251 pub largest_location: Option<Location>,
253 pub parameters: Vec<KeyValuePair>,
255}
256
257#[derive(Debug, Clone, PartialEq, Eq)]
259pub struct SubscribeError {
260 pub request_id: VarInt,
262 pub error_code: VarInt,
264 pub reason_phrase: Vec<u8>,
266 pub track_alias: VarInt,
268}
269
270#[derive(Debug, Clone, PartialEq, Eq)]
272pub struct SubscribeUpdate {
273 pub request_id: VarInt,
275 pub start_group: VarInt,
277 pub start_object: VarInt,
279 pub end_group: VarInt,
281 pub subscriber_priority: u8,
283 pub forward: Forward,
285 pub parameters: Vec<KeyValuePair>,
287}
288
289#[derive(Debug, Clone, PartialEq, Eq)]
291pub struct SubscribeDone {
292 pub request_id: VarInt,
294 pub status_code: VarInt,
296 pub stream_count: VarInt,
298 pub reason_phrase: Vec<u8>,
300}
301
302#[derive(Debug, Clone, PartialEq, Eq)]
304pub struct Unsubscribe {
305 pub request_id: VarInt,
307}
308
309#[derive(Debug, Clone, PartialEq, Eq)]
315pub struct Announce {
316 pub request_id: VarInt,
318 pub track_namespace: TrackNamespace,
320 pub parameters: Vec<KeyValuePair>,
322}
323
324#[derive(Debug, Clone, PartialEq, Eq)]
326pub struct AnnounceOk {
327 pub request_id: VarInt,
329}
330
331#[derive(Debug, Clone, PartialEq, Eq)]
333pub struct AnnounceError {
334 pub request_id: VarInt,
336 pub error_code: VarInt,
338 pub reason_phrase: Vec<u8>,
340}
341
342#[derive(Debug, Clone, PartialEq, Eq)]
344pub struct AnnounceCancel {
345 pub track_namespace: TrackNamespace,
347 pub error_code: VarInt,
349 pub reason_phrase: Vec<u8>,
351}
352
353#[derive(Debug, Clone, PartialEq, Eq)]
355pub struct Unannounce {
356 pub track_namespace: TrackNamespace,
358}
359
360#[derive(Debug, Clone, PartialEq, Eq)]
366pub struct SubscribeAnnounces {
367 pub request_id: VarInt,
369 pub track_namespace_prefix: TrackNamespace,
371 pub parameters: Vec<KeyValuePair>,
373}
374
375#[derive(Debug, Clone, PartialEq, Eq)]
377pub struct SubscribeAnnouncesOk {
378 pub request_id: VarInt,
380}
381
382#[derive(Debug, Clone, PartialEq, Eq)]
384pub struct SubscribeAnnouncesError {
385 pub request_id: VarInt,
387 pub error_code: VarInt,
389 pub reason_phrase: Vec<u8>,
391}
392
393#[derive(Debug, Clone, PartialEq, Eq)]
395pub struct UnsubscribeAnnounces {
396 pub track_namespace_prefix: TrackNamespace,
398}
399
400#[derive(Debug, Clone, PartialEq, Eq)]
406pub struct TrackStatusRequest {
407 pub request_id: VarInt,
409 pub track_namespace: TrackNamespace,
411 pub track_name: Vec<u8>,
413 pub parameters: Vec<KeyValuePair>,
415}
416
417#[derive(Debug, Clone, PartialEq, Eq)]
419pub struct TrackStatus {
420 pub request_id: VarInt,
422 pub status_code: VarInt,
424 pub largest_location: Location,
426 pub parameters: Vec<KeyValuePair>,
428}
429
430#[derive(Debug, Clone, Copy, PartialEq, Eq)]
436#[repr(u64)]
437pub enum FetchType {
438 Standalone = 1,
440 RelativeJoining = 2,
442 AbsoluteJoining = 3,
444}
445
446impl FetchType {
447 pub fn from_u64(v: u64) -> Option<Self> {
449 match v {
450 1 => Some(FetchType::Standalone),
451 2 => Some(FetchType::RelativeJoining),
452 3 => Some(FetchType::AbsoluteJoining),
453 _ => None,
454 }
455 }
456}
457
458#[derive(Debug, Clone, PartialEq, Eq)]
460pub struct Fetch {
461 pub request_id: VarInt,
463 pub subscriber_priority: u8,
465 pub group_order: GroupOrder,
467 pub fetch_type: FetchType,
469 pub fetch_payload: FetchPayload,
471 pub parameters: Vec<KeyValuePair>,
473}
474
475#[derive(Debug, Clone, PartialEq, Eq)]
477pub enum FetchPayload {
478 Standalone {
480 track_namespace: TrackNamespace,
482 track_name: Vec<u8>,
484 start_group: VarInt,
486 start_object: VarInt,
488 end_group: VarInt,
490 end_object: VarInt,
492 },
493 Joining {
495 joining_subscribe_id: VarInt,
497 joining_start: VarInt,
499 },
500}
501
502#[derive(Debug, Clone, PartialEq, Eq)]
504pub struct FetchOk {
505 pub request_id: VarInt,
507 pub group_order: GroupOrder,
509 pub end_of_track: u8,
516 pub end_location: Location,
518 pub parameters: Vec<KeyValuePair>,
520}
521
522#[derive(Debug, Clone, PartialEq, Eq)]
524pub struct FetchError {
525 pub request_id: VarInt,
527 pub error_code: VarInt,
529 pub reason_phrase: Vec<u8>,
531}
532
533#[derive(Debug, Clone, PartialEq, Eq)]
535pub struct FetchCancel {
536 pub request_id: VarInt,
538}
539
540fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
546 if !buf.has_remaining() {
547 return Err(CodecError::UnexpectedEnd);
548 }
549 Ok(buf.get_u8())
550}
551
552fn read_group_order(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
564 GroupOrder::from_u8(read_u8(buf)?).ok_or(CodecError::InvalidField)
565}
566
567fn read_forward(buf: &mut impl Buf) -> Result<Forward, CodecError> {
570 match read_u8(buf)? {
571 0 => Ok(Forward::DontForward),
572 1 => Ok(Forward::Forward),
573 other => Err(CodecError::InvalidForward(other)),
574 }
575}
576
577fn read_content_exists(buf: &mut impl Buf) -> Result<ContentExists, CodecError> {
580 match read_u8(buf)? {
581 0 => Ok(ContentExists::NoLargestLocation),
582 1 => Ok(ContentExists::HasLargestLocation),
583 other => Err(CodecError::InvalidContentExists(other)),
584 }
585}
586
587fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
598 if !buf.has_remaining() {
599 return Err(CodecError::UnexpectedEnd);
600 }
601 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
602 GroupOrder::Publisher => Err(CodecError::InvalidField),
603 order => Ok(order),
604 }
605}
606
607fn check_filter(
611 filter_type: VarInt,
612 start_group: &Option<VarInt>,
613 start_object: &Option<VarInt>,
614 end_group: &Option<VarInt>,
615) -> Result<(), CodecError> {
616 let value = filter_type.into_inner();
617 if value == 0 || value > 4 {
618 return Err(CodecError::InvalidFilterType(value));
619 }
620 let wants_start = value == 3 || value == 4;
621 if wants_start != start_group.is_some() || wants_start != start_object.is_some() {
622 return Err(CodecError::InvalidField);
623 }
624 if (value == 4) != end_group.is_some() {
625 return Err(CodecError::InvalidField);
626 }
627 Ok(())
628}
629
630fn check_content(
631 content_exists: ContentExists,
632 largest_location: &Option<Location>,
633) -> Result<(), CodecError> {
634 if (content_exists == ContentExists::HasLargestLocation) != largest_location.is_some() {
635 return Err(CodecError::InvalidField);
636 }
637 Ok(())
638}
639
640fn check_track_status(status_code: VarInt, largest_location: Location) -> Result<(), CodecError> {
651 let code = crate::draft11::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
652 .ok_or(CodecError::InvalidField)?;
653 if code.requires_zero_location()
654 && (largest_location.group.into_inner() != 0 || largest_location.object.into_inner() != 0)
655 {
656 return Err(CodecError::InvalidField);
657 }
658 Ok(())
659}
660
661fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
672 match message {
673 ControlMessage::Subscribe(m) => {
674 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
675 }
676 ControlMessage::SubscribeOk(m) => check_content(m.content_exists, &m.largest_location),
677 ControlMessage::Fetch(m) => {
678 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
679 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
680 return Err(CodecError::InvalidField);
681 }
682 Ok(())
683 }
684 _ => Ok(()),
685 }
686}
687
688fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
693 let order = match message {
694 ControlMessage::SubscribeOk(m) => m.group_order,
695 ControlMessage::FetchOk(m) => m.group_order,
696 _ => return Ok(()),
697 };
698 if order == GroupOrder::Publisher {
699 return Err(CodecError::InvalidField);
700 }
701 Ok(())
702}
703
704#[derive(Debug, Clone, PartialEq, Eq)]
706pub enum ControlMessage {
707 ClientSetup(ClientSetup),
709 ServerSetup(ServerSetup),
711 GoAway(GoAway),
713 MaxRequestId(MaxRequestId),
715 RequestsBlocked(RequestsBlocked),
717 Subscribe(Subscribe),
719 SubscribeOk(SubscribeOk),
721 SubscribeError(SubscribeError),
723 SubscribeUpdate(SubscribeUpdate),
725 SubscribeDone(SubscribeDone),
727 Unsubscribe(Unsubscribe),
729 Announce(Announce),
731 AnnounceOk(AnnounceOk),
733 AnnounceError(AnnounceError),
735 AnnounceCancel(AnnounceCancel),
737 Unannounce(Unannounce),
739 SubscribeAnnounces(SubscribeAnnounces),
741 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
743 SubscribeAnnouncesError(SubscribeAnnouncesError),
745 UnsubscribeAnnounces(UnsubscribeAnnounces),
747 TrackStatusRequest(TrackStatusRequest),
749 TrackStatus(TrackStatus),
751 Fetch(Fetch),
753 FetchOk(FetchOk),
755 FetchError(FetchError),
757 FetchCancel(FetchCancel),
759}
760
761fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
762 let total = namespace.field_bytes_len().saturating_add(track_name.len());
763 if total > MAX_FULL_TRACK_NAME_LENGTH {
764 return Err(CodecError::TrackNameTooLong);
765 }
766 Ok(())
767}
768
769fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
777 let len = VarInt::decode(buf)?.into_inner() as usize;
778 if len > MAX_REASON_PHRASE_LENGTH {
779 return Err(CodecError::ReasonPhraseTooLong);
780 }
781 types::read_bytes(buf, len)
782}
783
784fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
798 match message {
799 ControlMessage::Subscribe(m) => match (&m.start_group, &m.end_group) {
800 (Some(start_group), Some(end_group)) => {
801 check_group_range(start_group.into_inner(), end_group.into_inner())
802 }
803 _ => Ok(()),
804 },
805 ControlMessage::SubscribeUpdate(m) => {
806 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
807 }
808 ControlMessage::Fetch(m) => match &m.fetch_payload {
809 FetchPayload::Standalone {
810 start_group, start_object, end_group, end_object, ..
811 } => check_location_range(
812 start_group.into_inner(),
813 start_object.into_inner(),
814 end_group.into_inner(),
815 end_object.into_inner(),
816 ),
817 FetchPayload::Joining { .. } => Ok(()),
818 },
819 _ => Ok(()),
820 }
821}
822
823const AUTHORIZATION_TOKEN: u64 = 0x01;
830
831const DELIVERY_TIMEOUT: u64 = 0x02;
833
834const MAX_CACHE_DURATION: u64 = 0x04;
836
837const SETUP_PATH: u64 = 0x01;
839
840const SETUP_MAX_REQUEST_ID: u64 = 0x02;
842
843const SETUP_MAX_AUTH_TOKEN_CACHE_SIZE: u64 = 0x04;
845
846const KNOWN_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN, DELIVERY_TIMEOUT, MAX_CACHE_DURATION];
852
853const REPEATABLE_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN];
859
860const KNOWN_SETUP_PARAMETERS: &[u64] =
862 &[SETUP_PATH, SETUP_MAX_REQUEST_ID, SETUP_MAX_AUTH_TOKEN_CACHE_SIZE];
863
864const REPEATABLE_SETUP_PARAMETERS: &[u64] = &[];
876
877fn check_sender_parameters(
891 parameters: &[KeyValuePair],
892 repeatable: &[u64],
893) -> Result<(), CodecError> {
894 for (i, parameter) in parameters.iter().enumerate() {
895 let key = parameter.key.into_inner();
896 if repeatable.contains(&key) {
897 continue;
898 }
899 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
900 return Err(CodecError::DuplicateParameter(key));
901 }
902 }
903 Ok(())
904}
905
906fn check_receiver_parameters(
920 parameters: &[KeyValuePair],
921 known: &[u64],
922 repeatable: &[u64],
923) -> Result<(), CodecError> {
924 for (i, parameter) in parameters.iter().enumerate() {
925 let key = parameter.key.into_inner();
926 if repeatable.contains(&key) || !known.contains(&key) {
927 continue;
928 }
929 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
930 return Err(CodecError::DuplicateParameter(key));
931 }
932 }
933 Ok(())
934}
935
936fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
954 for parameter in parameters {
955 let key = parameter.key.into_inner();
956 if key != AUTH_TOKEN_PARAMETER_D11 {
957 continue;
958 }
959 match ¶meter.value {
960 KvpValue::Bytes(value) => {
961 AuthorizationToken::decode(key, value)?;
962 }
963 KvpValue::Varint(_) => {
968 return Err(CodecError::KeyValueFormatting {
969 key,
970 detail: "its value is a bare varint where the type defines a Token structure",
971 });
972 }
973 }
974 }
975 Ok(())
976}
977
978fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
980 let parameters = KeyValuePair::decode_list(buf)?;
981 check_receiver_parameters(¶meters, KNOWN_PARAMETERS, REPEATABLE_PARAMETERS)?;
982 check_authorization_tokens(¶meters)?;
983 Ok(parameters)
984}
985
986fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
996 check_sender_parameters(parameters, REPEATABLE_PARAMETERS)?;
997 check_authorization_tokens(parameters)?;
998 KeyValuePair::encode_list_checked(parameters, buf)?;
999 Ok(())
1000}
1001
1002fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
1004 let parameters = KeyValuePair::decode_list(buf)?;
1005 check_receiver_parameters(¶meters, KNOWN_SETUP_PARAMETERS, REPEATABLE_SETUP_PARAMETERS)?;
1006 Ok(parameters)
1007}
1008
1009fn encode_setup_parameters(
1011 parameters: &[KeyValuePair],
1012 buf: &mut impl BufMut,
1013) -> Result<(), CodecError> {
1014 check_sender_parameters(parameters, REPEATABLE_SETUP_PARAMETERS)?;
1015 KeyValuePair::encode_list_checked(parameters, buf)?;
1016 Ok(())
1017}
1018
1019impl ControlMessage {
1020 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1024 check_discriminators(self)?;
1025 check_group_order(self)?;
1026 check_ranges(self)?;
1027 let mut payload = Vec::with_capacity(256);
1028 self.encode_payload(&mut payload)?;
1029
1030 if payload.len() > MAX_MESSAGE_LENGTH {
1031 return Err(CodecError::MessageTooLong(payload.len()));
1032 }
1033
1034 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
1035 buf.put_u16(payload.len() as u16);
1037 buf.put_slice(&payload);
1038 Ok(())
1039 }
1040
1041 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
1045 let type_id = VarInt::decode(buf)?.into_inner();
1046 let msg_type =
1047 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
1048 if buf.remaining() < 2 {
1050 return Err(CodecError::UnexpectedEnd);
1051 }
1052 let payload_len = buf.get_u16() as usize;
1053 if buf.remaining() < payload_len {
1054 return Err(CodecError::UnexpectedEnd);
1055 }
1056 let payload_bytes = buf.copy_to_bytes(payload_len);
1057 let mut payload = &payload_bytes[..];
1058 let msg = match Self::decode_payload(msg_type, &mut payload) {
1059 Ok(msg) => msg,
1060 Err(
1066 CodecError::UnexpectedEnd
1067 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
1068 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
1069 crate::varint::VarIntError::UnexpectedEnd,
1070 ))
1071 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
1072 ) => {
1073 return Err(CodecError::ControlMessageLengthMismatch {
1074 declared: payload_len,
1075 detail: "its fields ran past the end",
1076 });
1077 }
1078 Err(e) => return Err(e),
1079 };
1080 check_ranges(&msg)?;
1081 if payload.has_remaining() {
1086 return Err(CodecError::ControlMessageLengthMismatch {
1087 declared: payload_len,
1088 detail: "its fields left bytes unread",
1089 });
1090 }
1091 Ok(msg)
1092 }
1093
1094 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1095 match self {
1096 ControlMessage::ClientSetup(m) => {
1097 VarInt::from_usize(m.supported_versions.len()).encode(buf);
1098 for v in &m.supported_versions {
1099 v.encode(buf);
1100 }
1101 encode_setup_parameters(&m.parameters, buf)?;
1102 }
1103 ControlMessage::ServerSetup(m) => {
1104 m.selected_version.encode(buf);
1105 encode_setup_parameters(&m.parameters, buf)?;
1106 }
1107 ControlMessage::GoAway(m) => {
1108 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
1109 return Err(CodecError::GoAwayUriTooLong);
1110 }
1111 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
1112 buf.put_slice(&m.new_session_uri);
1113 }
1114 ControlMessage::MaxRequestId(m) => {
1115 m.request_id.encode(buf);
1116 }
1117 ControlMessage::RequestsBlocked(m) => {
1118 m.maximum_request_id.encode(buf);
1119 }
1120 ControlMessage::Subscribe(m) => {
1121 m.request_id.encode(buf);
1122 m.track_alias.encode(buf);
1123 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1124 m.track_namespace.encode(buf);
1125 check_full_track_name(&m.track_namespace, &m.track_name)?;
1126 VarInt::from_usize(m.track_name.len()).encode(buf);
1127 buf.put_slice(&m.track_name);
1128 buf.put_u8(m.subscriber_priority);
1129 buf.put_u8(m.group_order as u8);
1130 buf.put_u8(m.forward as u8);
1131 m.filter_type.encode(buf);
1132 if let Some(sg) = &m.start_group {
1133 sg.encode(buf);
1134 }
1135 if let Some(so) = &m.start_object {
1136 so.encode(buf);
1137 }
1138 if let Some(eg) = &m.end_group {
1139 eg.encode(buf);
1140 }
1141 encode_parameters(&m.parameters, buf)?;
1142 }
1143 ControlMessage::SubscribeOk(m) => {
1144 m.request_id.encode(buf);
1145 m.expires.encode(buf);
1146 buf.put_u8(m.group_order as u8);
1147 buf.put_u8(m.content_exists as u8);
1148 if let Some(loc) = &m.largest_location {
1149 loc.encode(buf);
1150 }
1151 encode_parameters(&m.parameters, buf)?;
1152 }
1153 ControlMessage::SubscribeError(m) => {
1154 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1155 return Err(CodecError::ReasonPhraseTooLong);
1156 }
1157 m.request_id.encode(buf);
1158 m.error_code.encode(buf);
1159 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1160 buf.put_slice(&m.reason_phrase);
1161 m.track_alias.encode(buf);
1162 }
1163 ControlMessage::SubscribeUpdate(m) => {
1164 m.request_id.encode(buf);
1165 m.start_group.encode(buf);
1166 m.start_object.encode(buf);
1167 m.end_group.encode(buf);
1168 buf.put_u8(m.subscriber_priority);
1169 buf.put_u8(m.forward as u8);
1170 encode_parameters(&m.parameters, buf)?;
1171 }
1172 ControlMessage::SubscribeDone(m) => {
1173 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1174 return Err(CodecError::ReasonPhraseTooLong);
1175 }
1176 m.request_id.encode(buf);
1177 m.status_code.encode(buf);
1178 m.stream_count.encode(buf);
1179 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1180 buf.put_slice(&m.reason_phrase);
1181 }
1182 ControlMessage::Unsubscribe(m) => {
1183 m.request_id.encode(buf);
1184 }
1185 ControlMessage::Announce(m) => {
1186 m.request_id.encode(buf);
1187 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1188 m.track_namespace.encode(buf);
1189 encode_parameters(&m.parameters, buf)?;
1190 }
1191 ControlMessage::AnnounceOk(m) => {
1192 m.request_id.encode(buf);
1193 }
1194 ControlMessage::AnnounceError(m) => {
1195 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1196 return Err(CodecError::ReasonPhraseTooLong);
1197 }
1198 m.request_id.encode(buf);
1199 m.error_code.encode(buf);
1200 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1201 buf.put_slice(&m.reason_phrase);
1202 }
1203 ControlMessage::AnnounceCancel(m) => {
1204 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1205 return Err(CodecError::ReasonPhraseTooLong);
1206 }
1207 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1208 m.track_namespace.encode(buf);
1209 m.error_code.encode(buf);
1210 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1211 buf.put_slice(&m.reason_phrase);
1212 }
1213 ControlMessage::Unannounce(m) => {
1214 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1215 m.track_namespace.encode(buf);
1216 }
1217 ControlMessage::SubscribeAnnounces(m) => {
1218 m.request_id.encode(buf);
1219 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(11))?;
1220 m.track_namespace_prefix.encode(buf);
1221 encode_parameters(&m.parameters, buf)?;
1222 }
1223 ControlMessage::SubscribeAnnouncesOk(m) => {
1224 m.request_id.encode(buf);
1225 }
1226 ControlMessage::SubscribeAnnouncesError(m) => {
1227 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1228 return Err(CodecError::ReasonPhraseTooLong);
1229 }
1230 m.request_id.encode(buf);
1231 m.error_code.encode(buf);
1232 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1233 buf.put_slice(&m.reason_phrase);
1234 }
1235 ControlMessage::UnsubscribeAnnounces(m) => {
1236 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(11))?;
1237 m.track_namespace_prefix.encode(buf);
1238 }
1239 ControlMessage::TrackStatusRequest(m) => {
1240 m.request_id.encode(buf);
1241 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1242 m.track_namespace.encode(buf);
1243 check_full_track_name(&m.track_namespace, &m.track_name)?;
1244 VarInt::from_usize(m.track_name.len()).encode(buf);
1245 buf.put_slice(&m.track_name);
1246 encode_parameters(&m.parameters, buf)?;
1247 }
1248 ControlMessage::TrackStatus(m) => {
1249 m.request_id.encode(buf);
1250 check_track_status(m.status_code, m.largest_location)?;
1251 m.status_code.encode(buf);
1252 m.largest_location.encode(buf);
1253 encode_parameters(&m.parameters, buf)?;
1254 }
1255 ControlMessage::Fetch(m) => {
1256 m.request_id.encode(buf);
1257 buf.put_u8(m.subscriber_priority);
1258 buf.put_u8(m.group_order as u8);
1259 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1260 match &m.fetch_payload {
1261 FetchPayload::Standalone {
1262 track_namespace,
1263 track_name,
1264 start_group,
1265 start_object,
1266 end_group,
1267 end_object,
1268 } => {
1269 track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1270 track_namespace.encode(buf);
1271 check_full_track_name(track_namespace, track_name)?;
1272 VarInt::from_usize(track_name.len()).encode(buf);
1273 buf.put_slice(track_name);
1274 start_group.encode(buf);
1275 start_object.encode(buf);
1276 end_group.encode(buf);
1277 end_object.encode(buf);
1278 }
1279 FetchPayload::Joining { joining_subscribe_id, joining_start } => {
1280 joining_subscribe_id.encode(buf);
1281 joining_start.encode(buf);
1282 }
1283 }
1284 encode_parameters(&m.parameters, buf)?;
1285 }
1286 ControlMessage::FetchOk(m) => {
1287 m.request_id.encode(buf);
1288 buf.put_u8(m.group_order as u8);
1289 buf.put_u8(m.end_of_track);
1290 m.end_location.encode(buf);
1291 encode_parameters(&m.parameters, buf)?;
1292 }
1293 ControlMessage::FetchError(m) => {
1294 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1295 return Err(CodecError::ReasonPhraseTooLong);
1296 }
1297 m.request_id.encode(buf);
1298 m.error_code.encode(buf);
1299 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1300 buf.put_slice(&m.reason_phrase);
1301 }
1302 ControlMessage::FetchCancel(m) => {
1303 m.request_id.encode(buf);
1304 }
1305 }
1306 Ok(())
1307 }
1308
1309 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1310 match msg_type {
1311 MessageType::ClientSetup => {
1312 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1313 if num_versions == 0 {
1323 return Err(CodecError::InvalidField);
1324 }
1325 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1326 for _ in 0..num_versions {
1327 supported_versions.push(VarInt::decode(buf)?);
1328 }
1329 let parameters = decode_setup_parameters(buf)?;
1330 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1331 }
1332 MessageType::ServerSetup => {
1333 let selected_version = VarInt::decode(buf)?;
1334 let parameters = decode_setup_parameters(buf)?;
1335 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1336 }
1337 MessageType::GoAway => {
1338 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1339 if uri_len > MAX_GOAWAY_URI_LENGTH {
1340 return Err(CodecError::GoAwayUriTooLong);
1341 }
1342 let uri = types::read_bytes(buf, uri_len)?;
1343 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1344 }
1345 MessageType::MaxRequestId => {
1346 let request_id = VarInt::decode(buf)?;
1347 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1348 }
1349 MessageType::RequestsBlocked => {
1350 let maximum_request_id = VarInt::decode(buf)?;
1351 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1352 }
1353 MessageType::Subscribe => {
1354 let request_id = VarInt::decode(buf)?;
1355 let track_alias = VarInt::decode(buf)?;
1356 let track_namespace = TrackNamespace::decode(buf)?;
1357 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1358 let track_name = types::read_bytes(buf, track_name_len)?;
1359 check_full_track_name(&track_namespace, &track_name)?;
1360 if buf.remaining() < 1 {
1361 return Err(CodecError::UnexpectedEnd);
1362 }
1363 let subscriber_priority = buf.get_u8();
1364 let group_order = read_group_order(buf)?;
1365 let forward = read_forward(buf)?;
1366 let filter_type = VarInt::decode(buf)?;
1367 let ft_val = filter_type.into_inner();
1368 if ft_val == 0 || ft_val > 4 {
1369 return Err(CodecError::InvalidFilterType(ft_val));
1370 }
1371 let (start_group, start_object) = if ft_val == 3 || ft_val == 4 {
1372 (Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?))
1373 } else {
1374 (None, None)
1375 };
1376 let end_group = if ft_val == 4 { Some(VarInt::decode(buf)?) } else { None };
1377 let parameters = decode_parameters(buf)?;
1378 Ok(ControlMessage::Subscribe(Subscribe {
1379 request_id,
1380 track_alias,
1381 track_namespace,
1382 track_name,
1383 subscriber_priority,
1384 group_order,
1385 forward,
1386 filter_type,
1387 start_group,
1388 start_object,
1389 end_group,
1390 parameters,
1391 }))
1392 }
1393 MessageType::SubscribeOk => {
1394 let request_id = VarInt::decode(buf)?;
1395 let expires = VarInt::decode(buf)?;
1396 let group_order = read_group_order_response(buf)?;
1397 let content_exists = read_content_exists(buf)?;
1398 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1399 Some(Location::decode(buf)?)
1400 } else {
1401 None
1402 };
1403 let parameters = decode_parameters(buf)?;
1404 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1405 request_id,
1406 expires,
1407 group_order,
1408 content_exists,
1409 largest_location,
1410 parameters,
1411 }))
1412 }
1413 MessageType::SubscribeError => {
1414 let request_id = VarInt::decode(buf)?;
1415 let error_code = VarInt::decode(buf)?;
1416 let reason_phrase = read_reason_phrase(buf)?;
1417 let track_alias = VarInt::decode(buf)?;
1418 Ok(ControlMessage::SubscribeError(SubscribeError {
1419 request_id,
1420 error_code,
1421 reason_phrase,
1422 track_alias,
1423 }))
1424 }
1425 MessageType::SubscribeUpdate => {
1426 let request_id = VarInt::decode(buf)?;
1427 let start_group = VarInt::decode(buf)?;
1428 let start_object = VarInt::decode(buf)?;
1429 let end_group = VarInt::decode(buf)?;
1430 if buf.remaining() < 1 {
1431 return Err(CodecError::UnexpectedEnd);
1432 }
1433 let subscriber_priority = buf.get_u8();
1434 let forward = read_forward(buf)?;
1435 let parameters = decode_parameters(buf)?;
1436 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1437 request_id,
1438 start_group,
1439 start_object,
1440 end_group,
1441 subscriber_priority,
1442 forward,
1443 parameters,
1444 }))
1445 }
1446 MessageType::SubscribeDone => {
1447 let request_id = VarInt::decode(buf)?;
1448 let status_code = VarInt::decode(buf)?;
1449 let stream_count = VarInt::decode(buf)?;
1450 let reason_phrase = read_reason_phrase(buf)?;
1451 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1452 request_id,
1453 status_code,
1454 stream_count,
1455 reason_phrase,
1456 }))
1457 }
1458 MessageType::Unsubscribe => {
1459 let request_id = VarInt::decode(buf)?;
1460 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1461 }
1462 MessageType::Announce => {
1463 let request_id = VarInt::decode(buf)?;
1464 let track_namespace = TrackNamespace::decode(buf)?;
1465 let parameters = decode_parameters(buf)?;
1466 Ok(ControlMessage::Announce(Announce { request_id, track_namespace, parameters }))
1467 }
1468 MessageType::AnnounceOk => {
1469 let request_id = VarInt::decode(buf)?;
1470 Ok(ControlMessage::AnnounceOk(AnnounceOk { request_id }))
1471 }
1472 MessageType::AnnounceError => {
1473 let request_id = VarInt::decode(buf)?;
1474 let error_code = VarInt::decode(buf)?;
1475 let reason_phrase = read_reason_phrase(buf)?;
1476 Ok(ControlMessage::AnnounceError(AnnounceError {
1477 request_id,
1478 error_code,
1479 reason_phrase,
1480 }))
1481 }
1482 MessageType::AnnounceCancel => {
1483 let track_namespace = TrackNamespace::decode(buf)?;
1484 let error_code = VarInt::decode(buf)?;
1485 let reason_phrase = read_reason_phrase(buf)?;
1486 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1487 track_namespace,
1488 error_code,
1489 reason_phrase,
1490 }))
1491 }
1492 MessageType::Unannounce => {
1493 let track_namespace = TrackNamespace::decode(buf)?;
1494 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1495 }
1496 MessageType::SubscribeAnnounces => {
1497 let request_id = VarInt::decode(buf)?;
1498 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1499 let parameters = decode_parameters(buf)?;
1500 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1501 request_id,
1502 track_namespace_prefix,
1503 parameters,
1504 }))
1505 }
1506 MessageType::SubscribeAnnouncesOk => {
1507 let request_id = VarInt::decode(buf)?;
1508 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk { request_id }))
1509 }
1510 MessageType::SubscribeAnnouncesError => {
1511 let request_id = VarInt::decode(buf)?;
1512 let error_code = VarInt::decode(buf)?;
1513 let reason_phrase = read_reason_phrase(buf)?;
1514 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1515 request_id,
1516 error_code,
1517 reason_phrase,
1518 }))
1519 }
1520 MessageType::UnsubscribeAnnounces => {
1521 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1522 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1523 track_namespace_prefix,
1524 }))
1525 }
1526 MessageType::TrackStatusRequest => {
1527 let request_id = VarInt::decode(buf)?;
1528 let track_namespace = TrackNamespace::decode(buf)?;
1529 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1530 let track_name = types::read_bytes(buf, track_name_len)?;
1531 check_full_track_name(&track_namespace, &track_name)?;
1532 let parameters = decode_parameters(buf)?;
1533 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1534 request_id,
1535 track_namespace,
1536 track_name,
1537 parameters,
1538 }))
1539 }
1540 MessageType::TrackStatus => {
1541 let request_id = VarInt::decode(buf)?;
1542 let status_code = VarInt::decode(buf)?;
1543 let largest_location = Location::decode(buf)?;
1544 check_track_status(status_code, largest_location)?;
1545 let parameters = decode_parameters(buf)?;
1546 Ok(ControlMessage::TrackStatus(TrackStatus {
1547 request_id,
1548 status_code,
1549 largest_location,
1550 parameters,
1551 }))
1552 }
1553 MessageType::Fetch => {
1554 let request_id = VarInt::decode(buf)?;
1555 if buf.remaining() < 1 {
1556 return Err(CodecError::UnexpectedEnd);
1557 }
1558 let subscriber_priority = buf.get_u8();
1559 let group_order = read_group_order(buf)?;
1560 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1561 let fetch_type = FetchType::from_u64(fetch_type_val)
1562 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1563 let fetch_payload = match fetch_type {
1564 FetchType::Standalone => {
1565 let track_namespace = TrackNamespace::decode(buf)?;
1566 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1567 let track_name = types::read_bytes(buf, track_name_len)?;
1568 check_full_track_name(&track_namespace, &track_name)?;
1569 let start_group = VarInt::decode(buf)?;
1570 let start_object = VarInt::decode(buf)?;
1571 let end_group = VarInt::decode(buf)?;
1572 let end_object = VarInt::decode(buf)?;
1573 FetchPayload::Standalone {
1574 track_namespace,
1575 track_name,
1576 start_group,
1577 start_object,
1578 end_group,
1579 end_object,
1580 }
1581 }
1582 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1583 let joining_subscribe_id = VarInt::decode(buf)?;
1584 let joining_start = VarInt::decode(buf)?;
1585 FetchPayload::Joining { joining_subscribe_id, joining_start }
1586 }
1587 };
1588 let parameters = decode_parameters(buf)?;
1589 Ok(ControlMessage::Fetch(Fetch {
1590 request_id,
1591 subscriber_priority,
1592 group_order,
1593 fetch_type,
1594 fetch_payload,
1595 parameters,
1596 }))
1597 }
1598 MessageType::FetchOk => {
1599 let request_id = VarInt::decode(buf)?;
1600 let group_order = read_group_order_response(buf)?;
1601 let end_of_track = read_u8(buf)?;
1602 let end_location = Location::decode(buf)?;
1603 let parameters = decode_parameters(buf)?;
1604 Ok(ControlMessage::FetchOk(FetchOk {
1605 request_id,
1606 group_order,
1607 end_of_track,
1608 end_location,
1609 parameters,
1610 }))
1611 }
1612 MessageType::FetchError => {
1613 let request_id = VarInt::decode(buf)?;
1614 let error_code = VarInt::decode(buf)?;
1615 let reason_phrase = read_reason_phrase(buf)?;
1616 Ok(ControlMessage::FetchError(FetchError { request_id, error_code, reason_phrase }))
1617 }
1618 MessageType::FetchCancel => {
1619 let request_id = VarInt::decode(buf)?;
1620 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1621 }
1622 }
1623 }
1624
1625 pub fn message_type(&self) -> MessageType {
1627 match self {
1628 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1629 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1630 ControlMessage::GoAway(_) => MessageType::GoAway,
1631 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1632 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1633 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1634 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1635 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1636 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1637 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
1638 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1639 ControlMessage::Announce(_) => MessageType::Announce,
1640 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
1641 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
1642 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
1643 ControlMessage::Unannounce(_) => MessageType::Unannounce,
1644 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
1645 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
1646 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
1647 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
1648 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
1649 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1650 ControlMessage::Fetch(_) => MessageType::Fetch,
1651 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1652 ControlMessage::FetchError(_) => MessageType::FetchError,
1653 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1654 }
1655 }
1656}