1use crate::auth_token::{AuthorizationToken, AUTH_TOKEN_PARAMETER};
2use crate::error::{
3 CodecError, MAX_FULL_TRACK_NAME_LENGTH, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH,
4 MAX_REASON_PHRASE_LENGTH,
5};
6use crate::kvp::{KeyValuePair, KvpValue};
7use crate::types::*;
8pub use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
9use crate::varint::VarInt;
10use bytes::{Buf, BufMut};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14#[repr(u64)]
15pub enum MessageType {
16 SubscribeUpdate = 0x02,
18 Subscribe = 0x03,
20 SubscribeOk = 0x04,
22 SubscribeError = 0x05,
24 PublishNamespace = 0x06,
26 PublishNamespaceOk = 0x07,
28 PublishNamespaceError = 0x08,
30 PublishNamespaceDone = 0x09,
32 Unsubscribe = 0x0A,
34 PublishDone = 0x0B,
36 PublishNamespaceCancel = 0x0C,
38 TrackStatus = 0x0D,
40 TrackStatusOk = 0x0E,
42 TrackStatusError = 0x0F,
44 GoAway = 0x10,
46 SubscribeNamespace = 0x11,
48 SubscribeNamespaceOk = 0x12,
50 SubscribeNamespaceError = 0x13,
52 UnsubscribeNamespace = 0x14,
54 MaxRequestId = 0x15,
56 Fetch = 0x16,
58 FetchCancel = 0x17,
60 FetchOk = 0x18,
62 FetchError = 0x19,
64 RequestsBlocked = 0x1A,
66 Publish = 0x1D,
68 PublishOk = 0x1E,
70 PublishError = 0x1F,
72 ClientSetup = 0x20,
74 ServerSetup = 0x21,
76}
77
78impl MessageType {
79 pub fn from_id(id: u64) -> Option<Self> {
81 match id {
82 0x02 => Some(MessageType::SubscribeUpdate),
83 0x03 => Some(MessageType::Subscribe),
84 0x04 => Some(MessageType::SubscribeOk),
85 0x05 => Some(MessageType::SubscribeError),
86 0x06 => Some(MessageType::PublishNamespace),
87 0x07 => Some(MessageType::PublishNamespaceOk),
88 0x08 => Some(MessageType::PublishNamespaceError),
89 0x09 => Some(MessageType::PublishNamespaceDone),
90 0x0A => Some(MessageType::Unsubscribe),
91 0x0B => Some(MessageType::PublishDone),
92 0x0C => Some(MessageType::PublishNamespaceCancel),
93 0x0D => Some(MessageType::TrackStatus),
94 0x0E => Some(MessageType::TrackStatusOk),
95 0x0F => Some(MessageType::TrackStatusError),
96 0x10 => Some(MessageType::GoAway),
97 0x11 => Some(MessageType::SubscribeNamespace),
98 0x12 => Some(MessageType::SubscribeNamespaceOk),
99 0x13 => Some(MessageType::SubscribeNamespaceError),
100 0x14 => Some(MessageType::UnsubscribeNamespace),
101 0x15 => Some(MessageType::MaxRequestId),
102 0x16 => Some(MessageType::Fetch),
103 0x17 => Some(MessageType::FetchCancel),
104 0x18 => Some(MessageType::FetchOk),
105 0x19 => Some(MessageType::FetchError),
106 0x1A => Some(MessageType::RequestsBlocked),
107 0x1D => Some(MessageType::Publish),
108 0x1E => Some(MessageType::PublishOk),
109 0x1F => Some(MessageType::PublishError),
110 0x20 => Some(MessageType::ClientSetup),
111 0x21 => Some(MessageType::ServerSetup),
112 _ => None,
113 }
114 }
115
116 pub fn id(&self) -> u64 {
118 *self as u64
119 }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
128pub struct ClientSetup {
129 pub supported_versions: Vec<VarInt>,
131 pub parameters: Vec<KeyValuePair>,
133}
134
135#[derive(Debug, Clone, PartialEq, Eq)]
137pub struct ServerSetup {
138 pub selected_version: VarInt,
140 pub parameters: Vec<KeyValuePair>,
142}
143
144#[derive(Debug, Clone, PartialEq, Eq)]
146pub struct GoAway {
147 pub new_session_uri: Vec<u8>,
149}
150
151#[derive(Debug, Clone, PartialEq, Eq)]
153pub struct MaxRequestId {
154 pub request_id: VarInt,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct RequestsBlocked {
161 pub maximum_request_id: VarInt,
163}
164
165#[derive(Debug, Clone, PartialEq, Eq)]
171pub struct Subscribe {
172 pub request_id: VarInt,
174 pub track_namespace: TrackNamespace,
176 pub track_name: Vec<u8>,
178 pub subscriber_priority: u8,
180 pub group_order: GroupOrder,
182 pub forward: Forward,
184 pub filter_type: FilterType,
186 pub start_location: Option<Location>,
188 pub end_group: Option<VarInt>,
190 pub parameters: Vec<KeyValuePair>,
192}
193
194#[derive(Debug, Clone, PartialEq, Eq)]
196pub struct SubscribeOk {
197 pub request_id: VarInt,
199 pub track_alias: VarInt,
201 pub expires: VarInt,
203 pub group_order: GroupOrder,
205 pub content_exists: ContentExists,
207 pub largest_location: Option<Location>,
209 pub parameters: Vec<KeyValuePair>,
211}
212
213#[derive(Debug, Clone, PartialEq, Eq)]
215pub struct SubscribeError {
216 pub request_id: VarInt,
218 pub error_code: VarInt,
220 pub reason_phrase: Vec<u8>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
226pub struct SubscribeUpdate {
227 pub request_id: VarInt,
229 pub subscription_request_id: VarInt,
231 pub start_location: Location,
233 pub end_group: VarInt,
235 pub subscriber_priority: u8,
237 pub forward: Forward,
239 pub parameters: Vec<KeyValuePair>,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq)]
245pub struct Unsubscribe {
246 pub request_id: VarInt,
248}
249
250#[derive(Debug, Clone, PartialEq, Eq)]
256pub struct Publish {
257 pub request_id: VarInt,
259 pub track_namespace: TrackNamespace,
261 pub track_name: Vec<u8>,
263 pub track_alias: VarInt,
265 pub group_order: GroupOrder,
267 pub content_exists: ContentExists,
269 pub largest_location: Option<Location>,
271 pub forward: Forward,
273 pub parameters: Vec<KeyValuePair>,
275}
276
277#[derive(Debug, Clone, PartialEq, Eq)]
279pub struct PublishOk {
280 pub request_id: VarInt,
282 pub forward: Forward,
284 pub subscriber_priority: u8,
286 pub group_order: GroupOrder,
288 pub filter_type: FilterType,
290 pub start_location: Option<Location>,
292 pub end_group: Option<VarInt>,
294 pub parameters: Vec<KeyValuePair>,
296}
297
298#[derive(Debug, Clone, PartialEq, Eq)]
300pub struct PublishError {
301 pub request_id: VarInt,
303 pub error_code: VarInt,
305 pub reason_phrase: Vec<u8>,
307}
308
309#[derive(Debug, Clone, PartialEq, Eq)]
311pub struct PublishDone {
312 pub request_id: VarInt,
314 pub status_code: VarInt,
316 pub stream_count: VarInt,
318 pub reason_phrase: Vec<u8>,
320}
321
322#[derive(Debug, Clone, PartialEq, Eq)]
328pub struct PublishNamespace {
329 pub request_id: VarInt,
331 pub track_namespace: TrackNamespace,
333 pub parameters: Vec<KeyValuePair>,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq)]
339pub struct PublishNamespaceOk {
340 pub request_id: VarInt,
342}
343
344#[derive(Debug, Clone, PartialEq, Eq)]
346pub struct PublishNamespaceError {
347 pub request_id: VarInt,
349 pub error_code: VarInt,
351 pub reason_phrase: Vec<u8>,
353}
354
355#[derive(Debug, Clone, PartialEq, Eq)]
357pub struct PublishNamespaceDone {
358 pub track_namespace: TrackNamespace,
360}
361
362#[derive(Debug, Clone, PartialEq, Eq)]
364pub struct PublishNamespaceCancel {
365 pub track_namespace: TrackNamespace,
367 pub error_code: VarInt,
369 pub reason_phrase: Vec<u8>,
371}
372
373#[derive(Debug, Clone, PartialEq, Eq)]
379pub struct SubscribeNamespace {
380 pub request_id: VarInt,
382 pub track_namespace: TrackNamespace,
384 pub parameters: Vec<KeyValuePair>,
386}
387
388#[derive(Debug, Clone, PartialEq, Eq)]
390pub struct SubscribeNamespaceOk {
391 pub request_id: VarInt,
393}
394
395#[derive(Debug, Clone, PartialEq, Eq)]
397pub struct SubscribeNamespaceError {
398 pub request_id: VarInt,
400 pub error_code: VarInt,
402 pub reason_phrase: Vec<u8>,
404}
405
406#[derive(Debug, Clone, PartialEq, Eq)]
408pub struct UnsubscribeNamespace {
409 pub track_namespace_prefix: TrackNamespace,
411}
412
413#[derive(Debug, Clone, Copy, PartialEq, Eq)]
419#[repr(u64)]
420pub enum FetchType {
421 Standalone = 1,
423 RelativeJoining = 2,
425 AbsoluteJoining = 3,
427}
428
429impl FetchType {
430 pub fn from_u64(v: u64) -> Option<Self> {
432 match v {
433 1 => Some(FetchType::Standalone),
434 2 => Some(FetchType::RelativeJoining),
435 3 => Some(FetchType::AbsoluteJoining),
436 _ => None,
437 }
438 }
439}
440
441#[derive(Debug, Clone, PartialEq, Eq)]
443pub enum FetchPayload {
444 Standalone {
446 track_namespace: TrackNamespace,
448 track_name: Vec<u8>,
450 start_group: VarInt,
452 start_object: VarInt,
454 end_group: VarInt,
456 end_object: VarInt,
458 },
459 Joining {
461 joining_request_id: VarInt,
467 joining_start: VarInt,
469 },
470}
471
472#[derive(Debug, Clone, PartialEq, Eq)]
474pub struct Fetch {
475 pub request_id: VarInt,
477 pub subscriber_priority: u8,
479 pub group_order: GroupOrder,
481 pub fetch_type: FetchType,
483 pub fetch_payload: FetchPayload,
485 pub parameters: Vec<KeyValuePair>,
487}
488
489#[derive(Debug, Clone, PartialEq, Eq)]
491pub struct FetchOk {
492 pub request_id: VarInt,
494 pub group_order: GroupOrder,
496 pub end_of_track: u8,
498 pub end_location: Location,
500 pub parameters: Vec<KeyValuePair>,
502}
503
504#[derive(Debug, Clone, PartialEq, Eq)]
506pub struct FetchError {
507 pub request_id: VarInt,
509 pub error_code: VarInt,
511 pub reason_phrase: Vec<u8>,
513}
514
515#[derive(Debug, Clone, PartialEq, Eq)]
517pub struct FetchCancel {
518 pub request_id: VarInt,
520}
521
522#[derive(Debug, Clone, PartialEq, Eq)]
528pub struct TrackStatus {
529 pub request_id: VarInt,
531 pub track_namespace: TrackNamespace,
533 pub track_name: Vec<u8>,
535 pub subscriber_priority: u8,
537 pub group_order: GroupOrder,
539 pub forward: Forward,
541 pub filter_type: FilterType,
543 pub start_location: Option<Location>,
545 pub end_group: Option<VarInt>,
547 pub parameters: Vec<KeyValuePair>,
549}
550
551#[derive(Debug, Clone, PartialEq, Eq)]
553pub struct TrackStatusOk {
554 pub request_id: VarInt,
556 pub track_alias: VarInt,
558 pub expires: VarInt,
560 pub group_order: GroupOrder,
562 pub content_exists: ContentExists,
564 pub largest_location: Option<Location>,
566 pub parameters: Vec<KeyValuePair>,
568}
569
570#[derive(Debug, Clone, PartialEq, Eq)]
572pub struct TrackStatusError {
573 pub request_id: VarInt,
575 pub error_code: VarInt,
577 pub reason_phrase: Vec<u8>,
579}
580
581#[derive(Debug, Clone, PartialEq, Eq)]
587pub enum ControlMessage {
588 ClientSetup(ClientSetup),
590 ServerSetup(ServerSetup),
592 GoAway(GoAway),
594 MaxRequestId(MaxRequestId),
596 RequestsBlocked(RequestsBlocked),
598 Subscribe(Subscribe),
600 SubscribeOk(SubscribeOk),
602 SubscribeError(SubscribeError),
604 SubscribeUpdate(SubscribeUpdate),
606 Unsubscribe(Unsubscribe),
608 Publish(Publish),
610 PublishOk(PublishOk),
612 PublishError(PublishError),
614 PublishDone(PublishDone),
616 PublishNamespace(PublishNamespace),
618 PublishNamespaceOk(PublishNamespaceOk),
620 PublishNamespaceError(PublishNamespaceError),
622 PublishNamespaceDone(PublishNamespaceDone),
624 PublishNamespaceCancel(PublishNamespaceCancel),
626 SubscribeNamespace(SubscribeNamespace),
628 SubscribeNamespaceOk(SubscribeNamespaceOk),
630 SubscribeNamespaceError(SubscribeNamespaceError),
632 UnsubscribeNamespace(UnsubscribeNamespace),
634 Fetch(Fetch),
636 FetchOk(FetchOk),
638 FetchError(FetchError),
640 FetchCancel(FetchCancel),
642 TrackStatus(TrackStatus),
644 TrackStatusOk(TrackStatusOk),
646 TrackStatusError(TrackStatusError),
648}
649
650fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
667 if !buf.has_remaining() {
668 return Err(CodecError::UnexpectedEnd);
669 }
670 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
671 GroupOrder::Publisher => Err(CodecError::InvalidField),
672 order => Ok(order),
673 }
674}
675
676fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
681 let order = match message {
682 ControlMessage::SubscribeOk(m) => m.group_order,
683 ControlMessage::TrackStatusOk(m) => m.group_order,
684 ControlMessage::FetchOk(m) => m.group_order,
685 ControlMessage::Publish(m) => m.group_order,
686 ControlMessage::PublishOk(m) => m.group_order,
687 _ => return Ok(()),
688 };
689 if order == GroupOrder::Publisher {
690 return Err(CodecError::InvalidField);
691 }
692 Ok(())
693}
694
695fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
731 match message {
732 ControlMessage::Fetch(m) => {
733 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
734 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
735 return Err(CodecError::InvalidField);
736 }
737 }
738 ControlMessage::Subscribe(m) => {
739 let wants_start =
740 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
741 if wants_start != m.start_location.is_some() {
742 return Err(CodecError::InvalidField);
743 }
744 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
745 return Err(CodecError::InvalidField);
746 }
747 }
748 ControlMessage::SubscribeOk(m) => {
749 let has_location = m.content_exists == ContentExists::HasLargestLocation;
750 if has_location != m.largest_location.is_some() {
751 return Err(CodecError::InvalidField);
752 }
753 }
754 _ => {}
755 }
756 Ok(())
757}
758
759fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
775 let len = VarInt::decode(buf)?.into_inner() as usize;
776 if len > MAX_REASON_PHRASE_LENGTH {
777 return Err(CodecError::ReasonPhraseTooLong);
778 }
779 read_bytes(buf, len)
780}
781
782fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
783 let total = namespace.field_bytes_len().saturating_add(track_name.len());
784 if total > MAX_FULL_TRACK_NAME_LENGTH {
785 return Err(CodecError::TrackNameTooLong);
786 }
787 Ok(())
788}
789
790fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
804 match message {
805 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
806 (Some(start), Some(end_group)) => {
807 check_group_range(start.group.into_inner(), end_group.into_inner())
808 }
809 _ => Ok(()),
810 },
811 ControlMessage::SubscribeUpdate(m) => check_open_ended_group_range(
812 m.start_location.group.into_inner(),
813 m.end_group.into_inner(),
814 ),
815 ControlMessage::Fetch(m) => match &m.fetch_payload {
816 FetchPayload::Standalone {
817 start_group, start_object, end_group, end_object, ..
818 } => check_location_range(
819 start_group.into_inner(),
820 start_object.into_inner(),
821 end_group.into_inner(),
822 end_object.into_inner(),
823 ),
824 FetchPayload::Joining { .. } => Ok(()),
825 },
826 _ => Ok(()),
827 }
828}
829
830const REPEATABLE_PARAMETER: u64 = 0x03;
842
843const KNOWN_VERSION_SPECIFIC_PARAMETERS: &[u64] = &[0x02, 0x03, 0x04];
855
856const KNOWN_SETUP_PARAMETERS: &[u64] = &[0x01, 0x02, 0x03, 0x04, 0x05];
869
870fn check_no_duplicate_parameters_sent(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
882 for (i, parameter) in parameters.iter().enumerate() {
883 let key = parameter.key.into_inner();
884 if key == REPEATABLE_PARAMETER {
885 continue;
886 }
887 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
888 return Err(CodecError::DuplicateParameter(key));
889 }
890 }
891 Ok(())
892}
893
894fn check_no_duplicate_parameters_received(
912 parameters: &[KeyValuePair],
913 known: &[u64],
914) -> Result<(), CodecError> {
915 for (i, parameter) in parameters.iter().enumerate() {
916 let key = parameter.key.into_inner();
917 if key == REPEATABLE_PARAMETER || !known.contains(&key) {
918 continue;
919 }
920 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
921 return Err(CodecError::DuplicateParameter(key));
922 }
923 }
924 Ok(())
925}
926
927fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
942 for parameter in parameters {
943 let key = parameter.key.into_inner();
944 if key != AUTH_TOKEN_PARAMETER {
945 continue;
946 }
947 match ¶meter.value {
948 KvpValue::Bytes(value) => {
949 AuthorizationToken::decode(key, value)?;
950 }
951 KvpValue::Varint(_) => {
956 return Err(CodecError::KeyValueFormatting {
957 key,
958 detail: "its value is a bare varint where the type defines a Token structure",
959 });
960 }
961 }
962 }
963 Ok(())
964}
965
966fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
968 let parameters = KeyValuePair::decode_list(buf)?;
969 check_no_duplicate_parameters_received(¶meters, KNOWN_VERSION_SPECIFIC_PARAMETERS)?;
970 check_authorization_tokens(¶meters)?;
971 Ok(parameters)
972}
973
974fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
979 let parameters = KeyValuePair::decode_list(buf)?;
980 check_no_duplicate_parameters_received(¶meters, KNOWN_SETUP_PARAMETERS)?;
981 check_authorization_tokens(¶meters)?;
982 Ok(parameters)
983}
984
985fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
997 check_no_duplicate_parameters_sent(parameters)?;
998 check_authorization_tokens(parameters)?;
999 KeyValuePair::encode_list_checked(parameters, buf)?;
1000 Ok(())
1001}
1002
1003impl ControlMessage {
1004 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1008 check_discriminators(self)?;
1009 check_group_order(self)?;
1010 check_ranges(self)?;
1011 let mut payload = Vec::with_capacity(256);
1012 self.encode_payload(&mut payload)?;
1013
1014 if payload.len() > MAX_MESSAGE_LENGTH {
1015 return Err(CodecError::MessageTooLong(payload.len()));
1016 }
1017
1018 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
1019 buf.put_u16(payload.len() as u16);
1021 buf.put_slice(&payload);
1022 Ok(())
1023 }
1024
1025 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
1029 let type_id = VarInt::decode(buf)?.into_inner();
1030 let msg_type =
1031 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
1032 if buf.remaining() < 2 {
1034 return Err(CodecError::UnexpectedEnd);
1035 }
1036 let payload_len = buf.get_u16() as usize;
1037 if buf.remaining() < payload_len {
1038 return Err(CodecError::UnexpectedEnd);
1039 }
1040 let payload_bytes = buf.copy_to_bytes(payload_len);
1041 let mut payload = &payload_bytes[..];
1042 let msg = match Self::decode_payload(msg_type, &mut payload) {
1043 Ok(msg) => msg,
1044 Err(
1050 CodecError::UnexpectedEnd
1051 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
1052 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
1053 crate::varint::VarIntError::UnexpectedEnd,
1054 ))
1055 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
1056 ) => {
1057 return Err(CodecError::ControlMessageLengthMismatch {
1058 declared: payload_len,
1059 detail: "its fields ran past the end",
1060 });
1061 }
1062 Err(e) => return Err(e),
1063 };
1064 check_ranges(&msg)?;
1065 if payload.has_remaining() {
1070 return Err(CodecError::ControlMessageLengthMismatch {
1071 declared: payload_len,
1072 detail: "its fields left bytes unread",
1073 });
1074 }
1075 Ok(msg)
1076 }
1077
1078 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1079 match self {
1080 ControlMessage::ClientSetup(m) => {
1081 VarInt::from_usize(m.supported_versions.len()).encode(buf);
1082 for v in &m.supported_versions {
1083 v.encode(buf);
1084 }
1085 encode_parameters(&m.parameters, buf)?;
1086 }
1087 ControlMessage::ServerSetup(m) => {
1088 m.selected_version.encode(buf);
1089 encode_parameters(&m.parameters, buf)?;
1090 }
1091 ControlMessage::GoAway(m) => {
1092 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
1093 return Err(CodecError::GoAwayUriTooLong);
1094 }
1095 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
1096 buf.put_slice(&m.new_session_uri);
1097 }
1098 ControlMessage::MaxRequestId(m) => {
1099 m.request_id.encode(buf);
1100 }
1101 ControlMessage::RequestsBlocked(m) => {
1102 m.maximum_request_id.encode(buf);
1103 }
1104 ControlMessage::Subscribe(m) => {
1105 check_full_track_name(&m.track_namespace, &m.track_name)?;
1106 m.request_id.encode(buf);
1107 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1108 m.track_namespace.encode(buf);
1109 VarInt::from_usize(m.track_name.len()).encode(buf);
1110 buf.put_slice(&m.track_name);
1111 buf.put_u8(m.subscriber_priority);
1112 buf.put_u8(m.group_order as u8);
1113 buf.put_u8(m.forward as u8);
1114 VarInt::from_u64(m.filter_type as u64).unwrap().encode(buf);
1115 if let Some(loc) = &m.start_location {
1116 loc.encode(buf);
1117 }
1118 if let Some(eg) = &m.end_group {
1119 eg.encode(buf);
1120 }
1121 encode_parameters(&m.parameters, buf)?;
1122 }
1123 ControlMessage::SubscribeOk(m) => {
1124 m.request_id.encode(buf);
1125 m.track_alias.encode(buf);
1126 m.expires.encode(buf);
1127 buf.put_u8(m.group_order as u8);
1128 buf.put_u8(m.content_exists as u8);
1129 if let Some(loc) = &m.largest_location {
1130 loc.encode(buf);
1131 }
1132 encode_parameters(&m.parameters, buf)?;
1133 }
1134 ControlMessage::SubscribeError(m) => {
1135 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1136 return Err(CodecError::ReasonPhraseTooLong);
1137 }
1138 m.request_id.encode(buf);
1139 m.error_code.encode(buf);
1140 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1141 buf.put_slice(&m.reason_phrase);
1142 }
1143 ControlMessage::SubscribeUpdate(m) => {
1144 m.request_id.encode(buf);
1145 m.subscription_request_id.encode(buf);
1146 m.start_location.encode(buf);
1147 m.end_group.encode(buf);
1148 buf.put_u8(m.subscriber_priority);
1149 buf.put_u8(m.forward as u8);
1150 encode_parameters(&m.parameters, buf)?;
1151 }
1152 ControlMessage::Unsubscribe(m) => {
1153 m.request_id.encode(buf);
1154 }
1155 ControlMessage::Publish(m) => {
1156 check_full_track_name(&m.track_namespace, &m.track_name)?;
1157 m.request_id.encode(buf);
1158 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1159 m.track_namespace.encode(buf);
1160 VarInt::from_usize(m.track_name.len()).encode(buf);
1161 buf.put_slice(&m.track_name);
1162 m.track_alias.encode(buf);
1163 buf.put_u8(m.group_order as u8);
1164 buf.put_u8(m.content_exists as u8);
1165 if let Some(loc) = &m.largest_location {
1166 loc.encode(buf);
1167 }
1168 buf.put_u8(m.forward as u8);
1169 encode_parameters(&m.parameters, buf)?;
1170 }
1171 ControlMessage::PublishOk(m) => {
1172 m.request_id.encode(buf);
1173 buf.put_u8(m.forward as u8);
1174 buf.put_u8(m.subscriber_priority);
1175 buf.put_u8(m.group_order as u8);
1176 VarInt::from_u64(m.filter_type as u64).unwrap().encode(buf);
1177 if let Some(loc) = &m.start_location {
1178 loc.encode(buf);
1179 }
1180 if let Some(eg) = &m.end_group {
1181 eg.encode(buf);
1182 }
1183 encode_parameters(&m.parameters, buf)?;
1184 }
1185 ControlMessage::PublishError(m) => {
1186 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1187 return Err(CodecError::ReasonPhraseTooLong);
1188 }
1189 m.request_id.encode(buf);
1190 m.error_code.encode(buf);
1191 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1192 buf.put_slice(&m.reason_phrase);
1193 }
1194 ControlMessage::PublishDone(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.status_code.encode(buf);
1200 m.stream_count.encode(buf);
1201 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1202 buf.put_slice(&m.reason_phrase);
1203 }
1204 ControlMessage::PublishNamespace(m) => {
1205 m.request_id.encode(buf);
1206 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1207 m.track_namespace.encode(buf);
1208 encode_parameters(&m.parameters, buf)?;
1209 }
1210 ControlMessage::PublishNamespaceOk(m) => {
1211 m.request_id.encode(buf);
1212 }
1213 ControlMessage::PublishNamespaceError(m) => {
1214 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1215 return Err(CodecError::ReasonPhraseTooLong);
1216 }
1217 m.request_id.encode(buf);
1218 m.error_code.encode(buf);
1219 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1220 buf.put_slice(&m.reason_phrase);
1221 }
1222 ControlMessage::PublishNamespaceDone(m) => {
1223 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1224 m.track_namespace.encode(buf);
1225 }
1226 ControlMessage::PublishNamespaceCancel(m) => {
1227 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1228 return Err(CodecError::ReasonPhraseTooLong);
1229 }
1230 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1231 m.track_namespace.encode(buf);
1232 m.error_code.encode(buf);
1233 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1234 buf.put_slice(&m.reason_phrase);
1235 }
1236 ControlMessage::SubscribeNamespace(m) => {
1237 m.request_id.encode(buf);
1238 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1239 m.track_namespace.encode(buf);
1240 encode_parameters(&m.parameters, buf)?;
1241 }
1242 ControlMessage::SubscribeNamespaceOk(m) => {
1243 m.request_id.encode(buf);
1244 }
1245 ControlMessage::SubscribeNamespaceError(m) => {
1246 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1247 return Err(CodecError::ReasonPhraseTooLong);
1248 }
1249 m.request_id.encode(buf);
1250 m.error_code.encode(buf);
1251 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1252 buf.put_slice(&m.reason_phrase);
1253 }
1254 ControlMessage::UnsubscribeNamespace(m) => {
1255 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(14))?;
1256 m.track_namespace_prefix.encode(buf);
1257 }
1258 ControlMessage::Fetch(m) => {
1259 m.request_id.encode(buf);
1260 buf.put_u8(m.subscriber_priority);
1261 buf.put_u8(m.group_order as u8);
1262 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1263 match &m.fetch_payload {
1264 FetchPayload::Standalone {
1265 track_namespace,
1266 track_name,
1267 start_group,
1268 start_object,
1269 end_group,
1270 end_object,
1271 } => {
1272 check_full_track_name(track_namespace, track_name)?;
1273 track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1274 track_namespace.encode(buf);
1275 VarInt::from_usize(track_name.len()).encode(buf);
1276 buf.put_slice(track_name);
1277 start_group.encode(buf);
1278 start_object.encode(buf);
1279 end_group.encode(buf);
1280 end_object.encode(buf);
1281 }
1282 FetchPayload::Joining { joining_request_id, joining_start } => {
1283 joining_request_id.encode(buf);
1284 joining_start.encode(buf);
1285 }
1286 }
1287 encode_parameters(&m.parameters, buf)?;
1288 }
1289 ControlMessage::FetchOk(m) => {
1290 m.request_id.encode(buf);
1291 buf.put_u8(m.group_order as u8);
1292 buf.put_u8(m.end_of_track);
1293 m.end_location.encode(buf);
1294 encode_parameters(&m.parameters, buf)?;
1295 }
1296 ControlMessage::FetchError(m) => {
1297 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1298 return Err(CodecError::ReasonPhraseTooLong);
1299 }
1300 m.request_id.encode(buf);
1301 m.error_code.encode(buf);
1302 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1303 buf.put_slice(&m.reason_phrase);
1304 }
1305 ControlMessage::FetchCancel(m) => {
1306 m.request_id.encode(buf);
1307 }
1308 ControlMessage::TrackStatus(m) => {
1309 check_full_track_name(&m.track_namespace, &m.track_name)?;
1310 m.request_id.encode(buf);
1311 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1312 m.track_namespace.encode(buf);
1313 VarInt::from_usize(m.track_name.len()).encode(buf);
1314 buf.put_slice(&m.track_name);
1315 buf.put_u8(m.subscriber_priority);
1316 buf.put_u8(m.group_order as u8);
1317 buf.put_u8(m.forward as u8);
1318 VarInt::from_u64(m.filter_type as u64).unwrap().encode(buf);
1319 if let Some(loc) = &m.start_location {
1320 loc.encode(buf);
1321 }
1322 if let Some(eg) = &m.end_group {
1323 eg.encode(buf);
1324 }
1325 encode_parameters(&m.parameters, buf)?;
1326 }
1327 ControlMessage::TrackStatusOk(m) => {
1328 m.request_id.encode(buf);
1329 m.track_alias.encode(buf);
1330 m.expires.encode(buf);
1331 buf.put_u8(m.group_order as u8);
1332 buf.put_u8(m.content_exists as u8);
1333 if let Some(loc) = &m.largest_location {
1334 loc.encode(buf);
1335 }
1336 encode_parameters(&m.parameters, buf)?;
1337 }
1338 ControlMessage::TrackStatusError(m) => {
1339 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1340 return Err(CodecError::ReasonPhraseTooLong);
1341 }
1342 m.request_id.encode(buf);
1343 m.error_code.encode(buf);
1344 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1345 buf.put_slice(&m.reason_phrase);
1346 }
1347 }
1348 Ok(())
1349 }
1350
1351 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1352 match msg_type {
1353 MessageType::ClientSetup => {
1354 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1355 if num_versions == 0 {
1365 return Err(CodecError::InvalidField);
1366 }
1367 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1368 for _ in 0..num_versions {
1369 supported_versions.push(VarInt::decode(buf)?);
1370 }
1371 let parameters = decode_setup_parameters(buf)?;
1372 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1373 }
1374 MessageType::ServerSetup => {
1375 let selected_version = VarInt::decode(buf)?;
1376 let parameters = decode_setup_parameters(buf)?;
1377 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1378 }
1379 MessageType::GoAway => {
1380 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1381 if uri_len > MAX_GOAWAY_URI_LENGTH {
1387 return Err(CodecError::GoAwayUriTooLong);
1388 }
1389 let uri = read_bytes(buf, uri_len)?;
1390 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1391 }
1392 MessageType::MaxRequestId => {
1393 let request_id = VarInt::decode(buf)?;
1394 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1395 }
1396 MessageType::RequestsBlocked => {
1397 let maximum_request_id = VarInt::decode(buf)?;
1398 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1399 }
1400 MessageType::Subscribe => {
1401 let request_id = VarInt::decode(buf)?;
1402 let track_namespace = TrackNamespace::decode(buf)?;
1403 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1404 let track_name = read_bytes(buf, track_name_len)?;
1405 check_full_track_name(&track_namespace, &track_name)?;
1406 if buf.remaining() < 3 {
1407 return Err(CodecError::UnexpectedEnd);
1408 }
1409 let subscriber_priority = buf.get_u8();
1410 let group_order =
1411 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1412 let forward_val = buf.get_u8();
1413 let forward = match forward_val {
1414 0 => Forward::DontForward,
1415 1 => Forward::Forward,
1416 other => return Err(CodecError::InvalidForward(other)),
1417 };
1418 let filter_val = VarInt::decode(buf)?.into_inner();
1424 let filter_type = FilterType::from_u64(filter_val)
1425 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1426 let start_location = match filter_type {
1427 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1428 Some(Location::decode(buf)?)
1429 }
1430 _ => None,
1431 };
1432 let end_group = match filter_type {
1433 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1434 _ => None,
1435 };
1436 let parameters = decode_parameters(buf)?;
1437 Ok(ControlMessage::Subscribe(Subscribe {
1438 request_id,
1439 track_namespace,
1440 track_name,
1441 subscriber_priority,
1442 group_order,
1443 forward,
1444 filter_type,
1445 start_location,
1446 end_group,
1447 parameters,
1448 }))
1449 }
1450 MessageType::SubscribeOk => {
1451 let request_id = VarInt::decode(buf)?;
1452 let track_alias = VarInt::decode(buf)?;
1453 let expires = VarInt::decode(buf)?;
1454 if buf.remaining() < 2 {
1455 return Err(CodecError::UnexpectedEnd);
1456 }
1457 let group_order = read_group_order_response(buf)?;
1458 let content_exists_val = buf.get_u8();
1459 let content_exists = match content_exists_val {
1460 0 => ContentExists::NoLargestLocation,
1461 1 => ContentExists::HasLargestLocation,
1462 other => return Err(CodecError::InvalidContentExists(other)),
1463 };
1464 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1465 Some(Location::decode(buf)?)
1466 } else {
1467 None
1468 };
1469 let parameters = decode_parameters(buf)?;
1470 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1471 request_id,
1472 track_alias,
1473 expires,
1474 group_order,
1475 content_exists,
1476 largest_location,
1477 parameters,
1478 }))
1479 }
1480 MessageType::SubscribeError => {
1481 let request_id = VarInt::decode(buf)?;
1482 let error_code = VarInt::decode(buf)?;
1483 let reason_phrase = read_reason_phrase(buf)?;
1484 Ok(ControlMessage::SubscribeError(SubscribeError {
1485 request_id,
1486 error_code,
1487 reason_phrase,
1488 }))
1489 }
1490 MessageType::SubscribeUpdate => {
1491 let request_id = VarInt::decode(buf)?;
1492 let subscription_request_id = VarInt::decode(buf)?;
1493 let start_location = Location::decode(buf)?;
1494 let end_group = VarInt::decode(buf)?;
1495 if buf.remaining() < 2 {
1496 return Err(CodecError::UnexpectedEnd);
1497 }
1498 let subscriber_priority = buf.get_u8();
1499 let forward_val = buf.get_u8();
1500 let forward = match forward_val {
1501 0 => Forward::DontForward,
1502 1 => Forward::Forward,
1503 other => return Err(CodecError::InvalidForward(other)),
1504 };
1505 let parameters = decode_parameters(buf)?;
1506 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1507 request_id,
1508 subscription_request_id,
1509 start_location,
1510 end_group,
1511 subscriber_priority,
1512 forward,
1513 parameters,
1514 }))
1515 }
1516 MessageType::Unsubscribe => {
1517 let request_id = VarInt::decode(buf)?;
1518 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1519 }
1520 MessageType::Publish => {
1521 let request_id = VarInt::decode(buf)?;
1522 let track_namespace = TrackNamespace::decode(buf)?;
1523 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1524 let track_name = read_bytes(buf, track_name_len)?;
1525 check_full_track_name(&track_namespace, &track_name)?;
1526 let track_alias = VarInt::decode(buf)?;
1527 if buf.remaining() < 2 {
1528 return Err(CodecError::UnexpectedEnd);
1529 }
1530 let group_order = read_group_order_response(buf)?;
1531 let content_exists_val = buf.get_u8();
1532 let content_exists = match content_exists_val {
1533 0 => ContentExists::NoLargestLocation,
1534 1 => ContentExists::HasLargestLocation,
1535 other => return Err(CodecError::InvalidContentExists(other)),
1536 };
1537 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1538 Some(Location::decode(buf)?)
1539 } else {
1540 None
1541 };
1542 if buf.remaining() < 1 {
1543 return Err(CodecError::UnexpectedEnd);
1544 }
1545 let forward_val = buf.get_u8();
1546 let forward = match forward_val {
1547 0 => Forward::DontForward,
1548 1 => Forward::Forward,
1549 other => return Err(CodecError::InvalidForward(other)),
1550 };
1551 let parameters = decode_parameters(buf)?;
1552 Ok(ControlMessage::Publish(Publish {
1553 request_id,
1554 track_namespace,
1555 track_name,
1556 track_alias,
1557 group_order,
1558 content_exists,
1559 largest_location,
1560 forward,
1561 parameters,
1562 }))
1563 }
1564 MessageType::PublishOk => {
1565 let request_id = VarInt::decode(buf)?;
1566 if buf.remaining() < 3 {
1567 return Err(CodecError::UnexpectedEnd);
1568 }
1569 let forward_val = buf.get_u8();
1570 let forward = match forward_val {
1571 0 => Forward::DontForward,
1572 1 => Forward::Forward,
1573 other => return Err(CodecError::InvalidForward(other)),
1574 };
1575 let subscriber_priority = buf.get_u8();
1576 let group_order = read_group_order_response(buf)?;
1577 let filter_val = VarInt::decode(buf)?.into_inner();
1578 let filter_type = FilterType::from_u64(filter_val)
1579 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1580 let start_location = match filter_type {
1581 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1582 Some(Location::decode(buf)?)
1583 }
1584 _ => None,
1585 };
1586 let end_group = match filter_type {
1587 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1588 _ => None,
1589 };
1590 let parameters = decode_parameters(buf)?;
1591 Ok(ControlMessage::PublishOk(PublishOk {
1592 request_id,
1593 forward,
1594 subscriber_priority,
1595 group_order,
1596 filter_type,
1597 start_location,
1598 end_group,
1599 parameters,
1600 }))
1601 }
1602 MessageType::PublishError => {
1603 let request_id = VarInt::decode(buf)?;
1604 let error_code = VarInt::decode(buf)?;
1605 let reason_phrase = read_reason_phrase(buf)?;
1606 Ok(ControlMessage::PublishError(PublishError {
1607 request_id,
1608 error_code,
1609 reason_phrase,
1610 }))
1611 }
1612 MessageType::PublishDone => {
1613 let request_id = VarInt::decode(buf)?;
1614 let status_code = VarInt::decode(buf)?;
1615 let stream_count = VarInt::decode(buf)?;
1616 let reason_phrase = read_reason_phrase(buf)?;
1617 Ok(ControlMessage::PublishDone(PublishDone {
1618 request_id,
1619 status_code,
1620 stream_count,
1621 reason_phrase,
1622 }))
1623 }
1624 MessageType::PublishNamespace => {
1625 let request_id = VarInt::decode(buf)?;
1626 let track_namespace = TrackNamespace::decode(buf)?;
1627 let parameters = decode_parameters(buf)?;
1628 Ok(ControlMessage::PublishNamespace(PublishNamespace {
1629 request_id,
1630 track_namespace,
1631 parameters,
1632 }))
1633 }
1634 MessageType::PublishNamespaceOk => {
1635 let request_id = VarInt::decode(buf)?;
1636 Ok(ControlMessage::PublishNamespaceOk(PublishNamespaceOk { request_id }))
1637 }
1638 MessageType::PublishNamespaceError => {
1639 let request_id = VarInt::decode(buf)?;
1640 let error_code = VarInt::decode(buf)?;
1641 let reason_phrase = read_reason_phrase(buf)?;
1642 Ok(ControlMessage::PublishNamespaceError(PublishNamespaceError {
1643 request_id,
1644 error_code,
1645 reason_phrase,
1646 }))
1647 }
1648 MessageType::PublishNamespaceDone => {
1649 let track_namespace = TrackNamespace::decode(buf)?;
1650 Ok(ControlMessage::PublishNamespaceDone(PublishNamespaceDone { track_namespace }))
1651 }
1652 MessageType::PublishNamespaceCancel => {
1653 let track_namespace = TrackNamespace::decode(buf)?;
1654 let error_code = VarInt::decode(buf)?;
1655 let reason_phrase = read_reason_phrase(buf)?;
1656 Ok(ControlMessage::PublishNamespaceCancel(PublishNamespaceCancel {
1657 track_namespace,
1658 error_code,
1659 reason_phrase,
1660 }))
1661 }
1662 MessageType::SubscribeNamespace => {
1663 let request_id = VarInt::decode(buf)?;
1664 let track_namespace = TrackNamespace::decode(buf)?;
1665 let parameters = decode_parameters(buf)?;
1666 Ok(ControlMessage::SubscribeNamespace(SubscribeNamespace {
1667 request_id,
1668 track_namespace,
1669 parameters,
1670 }))
1671 }
1672 MessageType::SubscribeNamespaceOk => {
1673 let request_id = VarInt::decode(buf)?;
1674 Ok(ControlMessage::SubscribeNamespaceOk(SubscribeNamespaceOk { request_id }))
1675 }
1676 MessageType::SubscribeNamespaceError => {
1677 let request_id = VarInt::decode(buf)?;
1678 let error_code = VarInt::decode(buf)?;
1679 let reason_phrase = read_reason_phrase(buf)?;
1680 Ok(ControlMessage::SubscribeNamespaceError(SubscribeNamespaceError {
1681 request_id,
1682 error_code,
1683 reason_phrase,
1684 }))
1685 }
1686 MessageType::UnsubscribeNamespace => {
1687 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1688 Ok(ControlMessage::UnsubscribeNamespace(UnsubscribeNamespace {
1689 track_namespace_prefix,
1690 }))
1691 }
1692 MessageType::Fetch => {
1693 let request_id = VarInt::decode(buf)?;
1694 if buf.remaining() < 2 {
1695 return Err(CodecError::UnexpectedEnd);
1696 }
1697 let subscriber_priority = buf.get_u8();
1698 let group_order =
1699 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1700 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1701 let fetch_type = FetchType::from_u64(fetch_type_val)
1702 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1703 let fetch_payload = match fetch_type {
1704 FetchType::Standalone => {
1705 let track_namespace = TrackNamespace::decode(buf)?;
1706 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1707 let track_name = read_bytes(buf, track_name_len)?;
1708 check_full_track_name(&track_namespace, &track_name)?;
1709 let start_group = VarInt::decode(buf)?;
1710 let start_object = VarInt::decode(buf)?;
1711 let end_group = VarInt::decode(buf)?;
1712 let end_object = VarInt::decode(buf)?;
1713 FetchPayload::Standalone {
1714 track_namespace,
1715 track_name,
1716 start_group,
1717 start_object,
1718 end_group,
1719 end_object,
1720 }
1721 }
1722 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1723 let joining_request_id = VarInt::decode(buf)?;
1724 let joining_start = VarInt::decode(buf)?;
1725 FetchPayload::Joining { joining_request_id, joining_start }
1726 }
1727 };
1728 let parameters = decode_parameters(buf)?;
1729 Ok(ControlMessage::Fetch(Fetch {
1730 request_id,
1731 subscriber_priority,
1732 group_order,
1733 fetch_type,
1734 fetch_payload,
1735 parameters,
1736 }))
1737 }
1738 MessageType::FetchOk => {
1739 let request_id = VarInt::decode(buf)?;
1740 if buf.remaining() < 2 {
1741 return Err(CodecError::UnexpectedEnd);
1742 }
1743 let group_order = read_group_order_response(buf)?;
1744 let end_of_track = buf.get_u8();
1748 let end_location = Location::decode(buf)?;
1749 let parameters = decode_parameters(buf)?;
1750 Ok(ControlMessage::FetchOk(FetchOk {
1751 request_id,
1752 group_order,
1753 end_of_track,
1754 end_location,
1755 parameters,
1756 }))
1757 }
1758 MessageType::FetchError => {
1759 let request_id = VarInt::decode(buf)?;
1760 let error_code = VarInt::decode(buf)?;
1761 let reason_phrase = read_reason_phrase(buf)?;
1762 Ok(ControlMessage::FetchError(FetchError { request_id, error_code, reason_phrase }))
1763 }
1764 MessageType::FetchCancel => {
1765 let request_id = VarInt::decode(buf)?;
1766 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1767 }
1768 MessageType::TrackStatus => {
1769 let request_id = VarInt::decode(buf)?;
1770 let track_namespace = TrackNamespace::decode(buf)?;
1771 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1772 let track_name = read_bytes(buf, track_name_len)?;
1773 check_full_track_name(&track_namespace, &track_name)?;
1774 if buf.remaining() < 3 {
1775 return Err(CodecError::UnexpectedEnd);
1776 }
1777 let subscriber_priority = buf.get_u8();
1778 let group_order =
1779 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1780 let forward_val = buf.get_u8();
1781 let forward = match forward_val {
1782 0 => Forward::DontForward,
1783 1 => Forward::Forward,
1784 other => return Err(CodecError::InvalidForward(other)),
1785 };
1786 let filter_val = VarInt::decode(buf)?.into_inner();
1792 let filter_type = FilterType::from_u64(filter_val)
1793 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1794 let start_location = match filter_type {
1795 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1796 Some(Location::decode(buf)?)
1797 }
1798 _ => None,
1799 };
1800 let end_group = match filter_type {
1801 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1802 _ => None,
1803 };
1804 let parameters = decode_parameters(buf)?;
1805 Ok(ControlMessage::TrackStatus(TrackStatus {
1806 request_id,
1807 track_namespace,
1808 track_name,
1809 subscriber_priority,
1810 group_order,
1811 forward,
1812 filter_type,
1813 start_location,
1814 end_group,
1815 parameters,
1816 }))
1817 }
1818 MessageType::TrackStatusOk => {
1819 let request_id = VarInt::decode(buf)?;
1820 let track_alias = VarInt::decode(buf)?;
1821 let expires = VarInt::decode(buf)?;
1822 if buf.remaining() < 2 {
1823 return Err(CodecError::UnexpectedEnd);
1824 }
1825 let group_order = read_group_order_response(buf)?;
1826 let content_exists_val = buf.get_u8();
1827 let content_exists = match content_exists_val {
1828 0 => ContentExists::NoLargestLocation,
1829 1 => ContentExists::HasLargestLocation,
1830 other => return Err(CodecError::InvalidContentExists(other)),
1831 };
1832 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1833 Some(Location::decode(buf)?)
1834 } else {
1835 None
1836 };
1837 let parameters = decode_parameters(buf)?;
1838 Ok(ControlMessage::TrackStatusOk(TrackStatusOk {
1839 request_id,
1840 track_alias,
1841 expires,
1842 group_order,
1843 content_exists,
1844 largest_location,
1845 parameters,
1846 }))
1847 }
1848 MessageType::TrackStatusError => {
1849 let request_id = VarInt::decode(buf)?;
1850 let error_code = VarInt::decode(buf)?;
1851 let reason_phrase = read_reason_phrase(buf)?;
1852 Ok(ControlMessage::TrackStatusError(TrackStatusError {
1853 request_id,
1854 error_code,
1855 reason_phrase,
1856 }))
1857 }
1858 }
1859 }
1860
1861 pub fn message_type(&self) -> MessageType {
1863 match self {
1864 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1865 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1866 ControlMessage::GoAway(_) => MessageType::GoAway,
1867 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1868 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1869 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1870 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1871 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1872 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1873 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1874 ControlMessage::Publish(_) => MessageType::Publish,
1875 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1876 ControlMessage::PublishError(_) => MessageType::PublishError,
1877 ControlMessage::PublishDone(_) => MessageType::PublishDone,
1878 ControlMessage::PublishNamespace(_) => MessageType::PublishNamespace,
1879 ControlMessage::PublishNamespaceOk(_) => MessageType::PublishNamespaceOk,
1880 ControlMessage::PublishNamespaceError(_) => MessageType::PublishNamespaceError,
1881 ControlMessage::PublishNamespaceDone(_) => MessageType::PublishNamespaceDone,
1882 ControlMessage::PublishNamespaceCancel(_) => MessageType::PublishNamespaceCancel,
1883 ControlMessage::SubscribeNamespace(_) => MessageType::SubscribeNamespace,
1884 ControlMessage::SubscribeNamespaceOk(_) => MessageType::SubscribeNamespaceOk,
1885 ControlMessage::SubscribeNamespaceError(_) => MessageType::SubscribeNamespaceError,
1886 ControlMessage::UnsubscribeNamespace(_) => MessageType::UnsubscribeNamespace,
1887 ControlMessage::Fetch(_) => MessageType::Fetch,
1888 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1889 ControlMessage::FetchError(_) => MessageType::FetchError,
1890 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1891 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1892 ControlMessage::TrackStatusOk(_) => MessageType::TrackStatusOk,
1893 ControlMessage::TrackStatusError(_) => MessageType::TrackStatusError,
1894 }
1895 }
1896}