1use std::borrow::Cow;
108
109use crate::{
110 coding::{Decode, DecodeError, Encode},
111 ietf::{
112 namespace::{decode_namespace, encode_namespace},
113 FilterType, GroupOrder, Location, Message, Parameters, RequestId, Version,
114 },
115 Path,
116};
117
118#[derive(Clone, Debug)]
120pub struct PublishDone<'a> {
121 pub request_id: RequestId,
122 pub status_code: u64,
123 pub stream_count: u64,
124 pub reason_phrase: Cow<'a, str>,
125}
126
127impl<'a> Message for PublishDone<'a> {
128 const ID: u64 = 0x0b;
129
130 fn encode_msg<W: bytes::BufMut>(&self, w: &mut W, version: Version) {
131 self.request_id.encode(w, version);
132 self.status_code.encode(w, version);
133 self.stream_count.encode(w, version);
134 self.reason_phrase.encode(w, version);
135 }
136
137 fn decode_msg<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
138 let request_id = RequestId::decode(r, version)?;
139 let status_code = u64::decode(r, version)?;
140 let stream_count = u64::decode(r, version)?;
141 let reason_phrase = Cow::<str>::decode(r, version)?;
142
143 Ok(Self {
144 request_id,
145 status_code,
146 stream_count,
147 reason_phrase,
148 })
149 }
150}
151
152#[derive(Debug)]
153pub struct Publish<'a> {
154 pub request_id: RequestId,
155 pub track_namespace: Path<'a>,
156 pub track_name: Cow<'a, str>,
157 pub track_alias: u64,
158 pub group_order: GroupOrder,
159 pub largest_location: Option<Location>,
160 pub forward: bool,
161 }
163
164impl<'a> Message for Publish<'a> {
165 const ID: u64 = 0x1D;
166
167 fn encode_msg<W: bytes::BufMut>(&self, w: &mut W, version: Version) {
168 self.request_id.encode(w, version);
169 encode_namespace(w, &self.track_namespace, version);
170 self.track_name.encode(w, version);
171 self.track_alias.encode(w, version);
172 self.group_order.encode(w, version);
173 if let Some(location) = &self.largest_location {
174 true.encode(w, version);
175 location.encode(w, version);
176 } else {
177 false.encode(w, version);
178 }
179
180 self.forward.encode(w, version);
181 0u8.encode(w, version);
183 }
184
185 fn decode_msg<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
186 let request_id = RequestId::decode(r, version)?;
187 let track_namespace = decode_namespace(r, version)?;
188 let track_name = Cow::<str>::decode(r, version)?;
189 let track_alias = u64::decode(r, version)?;
190 let group_order = GroupOrder::decode(r, version)?;
191 let content_exists = bool::decode(r, version)?;
192 let largest_location = match content_exists {
193 true => Some(Location::decode(r, version)?),
194 false => None,
195 };
196 let forward = bool::decode(r, version)?;
197 let _params = Parameters::decode(r, version)?;
199 Ok(Self {
200 request_id,
201 track_namespace,
202 track_name,
203 track_alias,
204 group_order,
205 largest_location,
206 forward,
207 })
208 }
209}
210
211#[derive(Debug)]
212pub struct PublishOk {
213 pub request_id: RequestId,
214 pub forward: bool,
215 pub subscriber_priority: u8,
216 pub group_order: GroupOrder,
217 pub filter_type: FilterType,
218 }
220
221impl Message for PublishOk {
222 const ID: u64 = 0x1E;
223
224 fn encode_msg<W: bytes::BufMut>(&self, w: &mut W, version: Version) {
225 self.request_id.encode(w, version);
226 self.forward.encode(w, version);
227 self.subscriber_priority.encode(w, version);
228 self.group_order.encode(w, version);
229 self.filter_type.encode(w, version);
230 assert!(
231 matches!(self.filter_type, FilterType::LargestObject | FilterType::NextGroup),
232 "absolute subscribe not supported"
233 );
234 0u8.encode(w, version);
236 }
237
238 fn decode_msg<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
239 let request_id = RequestId::decode(r, version)?;
240 let forward = bool::decode(r, version)?;
241 let subscriber_priority = u8::decode(r, version)?;
242 let group_order = GroupOrder::decode(r, version)?;
243 let filter_type = FilterType::decode(r, version)?;
244 match filter_type {
245 FilterType::AbsoluteStart => {
246 let _start = Location::decode(r, version)?;
247 }
248 FilterType::AbsoluteRange => {
249 let _start = Location::decode(r, version)?;
250 let _end_group = u64::decode(r, version)?;
251 }
252 FilterType::NextGroup | FilterType::LargestObject => {}
253 };
254
255 let _params = Parameters::decode(r, version)?;
257
258 Ok(Self {
259 request_id,
260 forward,
261 subscriber_priority,
262 group_order,
263 filter_type,
264 })
265 }
266}
267
268#[derive(Debug)]
269pub struct PublishError<'a> {
270 pub request_id: RequestId,
271 pub error_code: u64,
272 pub reason_phrase: Cow<'a, str>,
273}
274impl<'a> Message for PublishError<'a> {
275 const ID: u64 = 0x1F;
276
277 fn encode_msg<W: bytes::BufMut>(&self, w: &mut W, version: Version) {
278 self.request_id.encode(w, version);
279 self.error_code.encode(w, version);
280 self.reason_phrase.encode(w, version);
281 }
282
283 fn decode_msg<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
284 let request_id = RequestId::decode(r, version)?;
285 let error_code = u64::decode(r, version)?;
286 let reason_phrase = Cow::<str>::decode(r, version)?;
287 Ok(Self {
288 request_id,
289 error_code,
290 reason_phrase,
291 })
292 }
293}