moqtap_codec/draft12/error_codes.rs
1//! Error, status and termination code registries defined by MoQ Transport draft-12.
2//!
3//! Draft-12 predates the IANA registries introduced in draft-14. Its code tables have
4//! exactly two columns, `Code` and `Reason`, and the `Reason` cell is a human-readable
5//! phrase rather than an ALLCAPS symbolic name — draft-12 gives its error, status and
6//! termination codes no symbolic names. (It does name other things that way, such as the
7//! control message types in section 8 and the authorization token operations in section
8//! 8.2.1.1, but not these.) Each variant name here is therefore derived mechanically from
9//! the `Reason` phrase.
10//!
11//! Each table is followed in the draft by a definition list giving one sentence per code.
12//! Every variant below carries its `Reason` phrase, so the mapping back to the table stays
13//! checkable, followed by that sentence. All 71 codes in these eight tables are described
14//! this way in the draft; nothing here is invented. Cross-references that the draft renders
15//! as hyperlinks appear as plain section numbers. One entry is repunctuated: the draft
16//! writes the `Expired Auth Token` sentence as "Authorization token has expired Section
17//! 8.2.1.1 )." with an unbalanced parenthesis, and it appears here in the "(see section
18//! 8.2.1.1)" form its neighbours use.
19//!
20//! Every `from_u64` returns `None` for a code the draft does not assign. Peers do send
21//! codes from other drafts and from private extensions, so an unrecognised code is a
22//! value to pass through, not a decoding failure.
23//!
24//! The eight registries transcribed here, with their draft-12 sections:
25//!
26//! - 3.4 Termination — [`SessionErrorCode`]
27//! - 8.9 SUBSCRIBE_ERROR — [`SubscribeErrorCode`]
28//! - 8.12 SUBSCRIBE_DONE — [`SubscribeDoneStatusCode`]
29//! - 8.15 PUBLISH_ERROR — [`PublishErrorCode`]
30//! - 8.18 FETCH_ERROR — [`FetchErrorCode`]
31//! - 8.24 ANNOUNCE_ERROR — [`AnnounceErrorCode`]
32//! - 8.29 SUBSCRIBE_ANNOUNCES_ERROR — [`SubscribeAnnouncesErrorCode`]
33//! - 9.4.3 Closing Subgroup Streams — [`StreamResetErrorCode`]
34//!
35//! [`SessionErrorCode`]: crate::draft12::error_codes::SessionErrorCode
36//! [`SubscribeErrorCode`]: crate::draft12::error_codes::SubscribeErrorCode
37//! [`SubscribeDoneStatusCode`]: crate::draft12::error_codes::SubscribeDoneStatusCode
38//! [`PublishErrorCode`]: crate::draft12::error_codes::PublishErrorCode
39//! [`FetchErrorCode`]: crate::draft12::error_codes::FetchErrorCode
40//! [`AnnounceErrorCode`]: crate::draft12::error_codes::AnnounceErrorCode
41//! [`SubscribeAnnouncesErrorCode`]: crate::draft12::error_codes::SubscribeAnnouncesErrorCode
42//! [`StreamResetErrorCode`]: crate::draft12::error_codes::StreamResetErrorCode
43//!
44//! Draft-12 reserves no code ranges for greasing in any of these tables.
45
46/// Session termination error codes (draft-12 section 3.4, Termination).
47///
48/// Sent when closing the session: "When terminating the Session, the application MAY use
49/// any error message and SHOULD use a relevant code, as defined below".
50///
51/// The table jumps from 0x9 to 0x10; 0xA through 0xF are unassigned.
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53#[repr(u64)]
54pub enum SessionErrorCode {
55 /// `No Error` — The session is being terminated without an error.
56 NoError = 0x0,
57 /// `Internal Error` — An implementation specific error occurred.
58 InternalError = 0x1,
59 /// `Unauthorized` — The client is not authorized to establish a session.
60 Unauthorized = 0x2,
61 /// `Protocol Violation` — The remote endpoint performed an action that was disallowed
62 /// by the specification.
63 ProtocolViolation = 0x3,
64 /// `Invalid Request ID` — The session was closed because the endpoint used a Request ID
65 /// that was smaller than or equal to a previously received request ID, or the
66 /// least-significant bit of the request ID was incorrect for the endpoint.
67 InvalidRequestId = 0x4,
68 /// `Duplicate Track Alias` — The endpoint attempted to use a Track Alias that was
69 /// already in use.
70 DuplicateTrackAlias = 0x5,
71 /// `Key-Value Formatting Error` — The key-value pair has a formatting error.
72 KeyValueFormattingError = 0x6,
73 /// `Too Many Requests` — The session was closed because the endpoint used a Request ID
74 /// equal to or larger than the current Maximum Request ID.
75 TooManyRequests = 0x7,
76 /// `Invalid Path` — The PATH parameter was used by a server, on a WebTransport session,
77 /// or the server does not support the path.
78 InvalidPath = 0x8,
79 /// `Malformed Path` — The PATH parameter does not conform to the rules in section
80 /// 8.3.2.1.
81 MalformedPath = 0x9,
82 /// `GOAWAY Timeout` — The session was closed because the peer took too long to close
83 /// the session in response to a GOAWAY (section 8.4) message. See session migration
84 /// (section 3.5).
85 GoawayTimeout = 0x10,
86 /// `Control Message Timeout` — The session was closed because the peer took too long to
87 /// respond to a control message.
88 ControlMessageTimeout = 0x11,
89 /// `Data Stream Timeout` — The session was closed because the peer took too long to
90 /// send data expected on an open Data Stream (see section 9). This includes fields of a
91 /// stream header or an object header within a data stream. If an endpoint times out
92 /// waiting for a new object header on an open subgroup stream, it MAY send a
93 /// STOP_SENDING on that stream or terminate the subscription.
94 DataStreamTimeout = 0x12,
95 /// `Auth Token Cache Overflow` — The Session limit (section 8.3.2.3) of the size of all
96 /// registered Authorization tokens has been exceeded.
97 AuthTokenCacheOverflow = 0x13,
98 /// `Duplicate Auth Token Alias` — Authorization Token attempted to register an Alias
99 /// that was in use (see section 8.2.1.1).
100 DuplicateAuthTokenAlias = 0x14,
101 /// `Version Negotiation Failed` — The client didn't offer a version supported by the
102 /// server.
103 VersionNegotiationFailed = 0x15,
104 /// `Malformed Auth Token` — Invalid Auth Token serialization during registration (see
105 /// section 8.2.1.1).
106 MalformedAuthToken = 0x16,
107 /// `Unknown Auth Token Alias` — No registered token found for the provided Alias (see
108 /// section 8.2.1.1).
109 UnknownAuthTokenAlias = 0x17,
110 /// `Expired Auth Token` — Authorization token has expired (see section 8.2.1.1).
111 ExpiredAuthToken = 0x18,
112}
113
114/// SUBSCRIBE_ERROR codes (draft-12 section 8.9).
115///
116/// The table assigns 0x0 through 0x5, then 0x10 and 0x12; 0x11 is unassigned. The session
117/// termination table carries three auth-token codes at 0x16, 0x17 and 0x18, exactly 6 above
118/// 0x10, 0x11 and 0x12, so the unassigned slot lines up with `Unknown Auth Token Alias`,
119/// which has no request-level counterpart. The draft does not say this is why the gap is
120/// there.
121#[derive(Debug, Clone, Copy, PartialEq, Eq)]
122#[repr(u64)]
123pub enum SubscribeErrorCode {
124 /// `Internal Error` — An implementation specific or generic error occurred.
125 InternalError = 0x0,
126 /// `Unauthorized` — The subscriber is not authorized to subscribe to the given track.
127 Unauthorized = 0x1,
128 /// `Timeout` — The subscription could not be completed before an implementation
129 /// specific timeout. For example, a relay could not establish an upstream subscription
130 /// within the timeout.
131 Timeout = 0x2,
132 /// `Not Supported` — The endpoint does not support the SUBSCRIBE method.
133 NotSupported = 0x3,
134 /// `Track Does Not Exist` — The requested track is not available at the publisher.
135 TrackDoesNotExist = 0x4,
136 /// `Invalid Range` — The end of the SUBSCRIBE range is earlier than the beginning, or
137 /// the end of the range has already been published.
138 InvalidRange = 0x5,
139 /// `Malformed Auth Token` — Invalid Auth Token serialization during registration (see
140 /// section 8.2.1.1).
141 MalformedAuthToken = 0x10,
142 /// `Expired Auth Token` — Authorization token has expired (see section 8.2.1.1).
143 ExpiredAuthToken = 0x12,
144}
145
146/// SUBSCRIBE_DONE status codes (draft-12 section 8.12).
147///
148/// The SUBSCRIBE_DONE message carries a Status Code field, described by the draft as "an
149/// integer status code indicating why the subscription ended". The draft does not divide
150/// these codes into successes and failures.
151#[derive(Debug, Clone, Copy, PartialEq, Eq)]
152#[repr(u64)]
153pub enum SubscribeDoneStatusCode {
154 /// `Internal Error` — An implementation specific or generic error occurred.
155 InternalError = 0x0,
156 /// `Unauthorized` — The subscriber is no longer authorized to subscribe to the given
157 /// track.
158 Unauthorized = 0x1,
159 /// `Track Ended` — The track is no longer being published.
160 TrackEnded = 0x2,
161 /// `Subscription Ended` — The publisher reached the end of an associated Subscribe
162 /// filter.
163 SubscriptionEnded = 0x3,
164 /// `Going Away` — The subscriber or publisher issued a GOAWAY message.
165 GoingAway = 0x4,
166 /// `Expired` — The publisher reached the timeout specified in SUBSCRIBE_OK.
167 Expired = 0x5,
168 /// `Too Far Behind` — The publisher's queue of objects to be sent to the given
169 /// subscriber exceeds its implementation defined limit.
170 TooFarBehind = 0x6,
171 /// `Malformed Track` — A relay publisher detected the track was malformed (see section
172 /// 2.5).
173 MalformedTrack = 0x7,
174}
175
176/// PUBLISH_ERROR codes (draft-12 section 8.15).
177///
178/// PUBLISH, PUBLISH_OK and PUBLISH_ERROR are new in draft-12; draft-11's control message
179/// table has no PUBLISH entries. Unlike the other request-error tables this one assigns no
180/// auth-token codes at 0x10 or 0x12; its five entries are contiguous from 0x0.
181#[derive(Debug, Clone, Copy, PartialEq, Eq)]
182#[repr(u64)]
183pub enum PublishErrorCode {
184 /// `Internal Error` — An implementation specific or generic error occurred.
185 InternalError = 0x0,
186 /// `Unauthorized` — The publisher is not authorized to publish the given namespace or
187 /// track.
188 Unauthorized = 0x1,
189 /// `Timeout` — The subscription could not be established before an implementation
190 /// specific timeout.
191 Timeout = 0x2,
192 /// `Not Supported` — The endpoint does not support the PUBLISH method.
193 NotSupported = 0x3,
194 /// `Uninterested` — The namespace or track is not of interest to the endpoint.
195 Uninterested = 0x4,
196}
197
198/// FETCH_ERROR codes (draft-12 section 8.18).
199///
200/// Assigns 0x0 through 0x9, then 0x10 and 0x12; 0x11 is unassigned.
201///
202/// The draft names 0x7 inconsistently: the table cell reads "Invalid Joining Request ID"
203/// while the definition list below it reads "Invalid Joining Subscribe ID". The table is
204/// the code point assignment and is followed here; draft-14 settles the question by naming
205/// the same code INVALID_JOINING_REQUEST_ID.
206#[derive(Debug, Clone, Copy, PartialEq, Eq)]
207#[repr(u64)]
208pub enum FetchErrorCode {
209 /// `Internal Error` — An implementation specific or generic error occurred.
210 InternalError = 0x0,
211 /// `Unauthorized` — The subscriber is not authorized to fetch from the given track.
212 Unauthorized = 0x1,
213 /// `Timeout` — The fetch could not be completed before an implementation specific
214 /// timeout. For example, a relay could not FETCH missing objects within the timeout.
215 Timeout = 0x2,
216 /// `Not Supported` — The endpoint does not support the FETCH method.
217 NotSupported = 0x3,
218 /// `Track Does Not Exist` — The requested track is not available at the publisher.
219 TrackDoesNotExist = 0x4,
220 /// `Invalid Range` — The end of the requested range is earlier than the beginning, the
221 /// start of the requested range is beyond the Largest Location, or the track has not
222 /// published any Objects yet.
223 InvalidRange = 0x5,
224 /// `No Objects` — No Objects exist between the requested Start and End Locations.
225 NoObjects = 0x6,
226 /// `Invalid Joining Request ID` — The joining Fetch referenced a Request ID that did not
227 /// belong to an active Subscription.
228 InvalidJoiningRequestId = 0x7,
229 /// `Unknown Status in Range` — The requested range contains objects with unknown status.
230 UnknownStatusInRange = 0x8,
231 /// `Malformed Track` — A relay publisher detected the track was malformed (see section
232 /// 2.5).
233 MalformedTrack = 0x9,
234 /// `Malformed Auth Token` — Invalid Auth Token serialization during registration (see
235 /// section 8.2.1.1).
236 MalformedAuthToken = 0x10,
237 /// `Expired Auth Token` — Authorization token has expired (see section 8.2.1.1).
238 ExpiredAuthToken = 0x12,
239}
240
241/// ANNOUNCE_ERROR codes (draft-12 section 8.24).
242///
243/// Assigns 0x0 through 0x4, then 0x10 and 0x12; 0x11 is unassigned.
244#[derive(Debug, Clone, Copy, PartialEq, Eq)]
245#[repr(u64)]
246pub enum AnnounceErrorCode {
247 /// `Internal Error` — An implementation specific or generic error occurred.
248 InternalError = 0x0,
249 /// `Unauthorized` — The subscriber is not authorized to announce the given namespace.
250 Unauthorized = 0x1,
251 /// `Timeout` — The announce could not be completed before an implementation specific
252 /// timeout.
253 Timeout = 0x2,
254 /// `Not Supported` — The endpoint does not support the ANNOUNCE method.
255 NotSupported = 0x3,
256 /// `Uninterested` — The namespace is not of interest to the endpoint.
257 Uninterested = 0x4,
258 /// `Malformed Auth Token` — Invalid Auth Token serialization during registration (see
259 /// section 8.2.1.1).
260 MalformedAuthToken = 0x10,
261 /// `Expired Auth Token` — Authorization token has expired (see section 8.2.1.1).
262 ExpiredAuthToken = 0x12,
263}
264
265/// SUBSCRIBE_ANNOUNCES_ERROR codes (draft-12 section 8.29).
266///
267/// Assigns 0x0 through 0x5, then 0x10 and 0x12; 0x11 is unassigned.
268#[derive(Debug, Clone, Copy, PartialEq, Eq)]
269#[repr(u64)]
270pub enum SubscribeAnnouncesErrorCode {
271 /// `Internal Error` — An implementation specific or generic error occurred.
272 InternalError = 0x0,
273 /// `Unauthorized` — The subscriber is not authorized to subscribe to the given namespace
274 /// prefix.
275 Unauthorized = 0x1,
276 /// `Timeout` — The operation could not be completed before an implementation specific
277 /// timeout.
278 Timeout = 0x2,
279 /// `Not Supported` — The endpoint does not support the SUBSCRIBE_ANNOUNCES method.
280 NotSupported = 0x3,
281 /// `Namespace Prefix Unknown` — The namespace prefix is not available for subscription.
282 NamespacePrefixUnknown = 0x4,
283 /// `Namespace Prefix Overlap` — The namespace prefix overlaps with another
284 /// SUBSCRIBE_ANNOUNCES in the same session.
285 NamespacePrefixOverlap = 0x5,
286 /// `Malformed Auth Token` — Invalid Auth Token serialization during registration (see
287 /// section 8.2.1.1).
288 MalformedAuthToken = 0x10,
289 /// `Expired Auth Token` — Authorization token has expired (see section 8.2.1.1).
290 ExpiredAuthToken = 0x12,
291}
292
293/// Data stream reset error codes (draft-12 section 9.4.3, Closing Subgroup Streams).
294///
295/// Carried in the RESET_STREAM or RESET_STREAM_AT frame that tears down a subgroup stream:
296/// "The application SHOULD use a relevant error code in RESET_STREAM or RESET_STREAM_AT, as
297/// defined below"
298#[derive(Debug, Clone, Copy, PartialEq, Eq)]
299#[repr(u64)]
300pub enum StreamResetErrorCode {
301 /// `Internal Error` — An implementation specific error.
302 InternalError = 0x0,
303 /// `Cancelled` — The subscriber requested cancellation via UNSUBSCRIBE, FETCH_CANCEL or
304 /// STOP_SENDING, or the publisher ended the subscription, in which case SUBSCRIBE_DONE
305 /// (section 8.12) will have a more detailed status code.
306 Cancelled = 0x1,
307 /// `Delivery Timeout` — The DELIVERY TIMEOUT (section 8.2.1.2) was exceeded for this
308 /// stream.
309 DeliveryTimeout = 0x2,
310 /// `Session Closed` — The publisher session is being closed.
311 SessionClosed = 0x3,
312}
313
314impl SessionErrorCode {
315 /// Every session termination code draft-12 assigns, in ascending wire order.
316 ///
317 /// This is the set [`Self::from_u64`] accepts, written out so that it can
318 /// be enumerated: nothing can iterate an enum's variants, so a caller that
319 /// wants the registry has to be handed it. Writing it down is also what
320 /// lets a test state its claims about the registry itself rather than about
321 /// the range some sweep happens to reach.
322 pub const ALL: &[SessionErrorCode] = &[
323 SessionErrorCode::NoError,
324 SessionErrorCode::InternalError,
325 SessionErrorCode::Unauthorized,
326 SessionErrorCode::ProtocolViolation,
327 SessionErrorCode::InvalidRequestId,
328 SessionErrorCode::DuplicateTrackAlias,
329 SessionErrorCode::KeyValueFormattingError,
330 SessionErrorCode::TooManyRequests,
331 SessionErrorCode::InvalidPath,
332 SessionErrorCode::MalformedPath,
333 SessionErrorCode::GoawayTimeout,
334 SessionErrorCode::ControlMessageTimeout,
335 SessionErrorCode::DataStreamTimeout,
336 SessionErrorCode::AuthTokenCacheOverflow,
337 SessionErrorCode::DuplicateAuthTokenAlias,
338 SessionErrorCode::VersionNegotiationFailed,
339 SessionErrorCode::MalformedAuthToken,
340 SessionErrorCode::UnknownAuthTokenAlias,
341 SessionErrorCode::ExpiredAuthToken,
342 ];
343
344 /// Convert a raw u64 to a `SessionErrorCode`, if valid.
345 pub fn from_u64(v: u64) -> Option<Self> {
346 match v {
347 0x0 => Some(SessionErrorCode::NoError),
348 0x1 => Some(SessionErrorCode::InternalError),
349 0x2 => Some(SessionErrorCode::Unauthorized),
350 0x3 => Some(SessionErrorCode::ProtocolViolation),
351 0x4 => Some(SessionErrorCode::InvalidRequestId),
352 0x5 => Some(SessionErrorCode::DuplicateTrackAlias),
353 0x6 => Some(SessionErrorCode::KeyValueFormattingError),
354 0x7 => Some(SessionErrorCode::TooManyRequests),
355 0x8 => Some(SessionErrorCode::InvalidPath),
356 0x9 => Some(SessionErrorCode::MalformedPath),
357 0x10 => Some(SessionErrorCode::GoawayTimeout),
358 0x11 => Some(SessionErrorCode::ControlMessageTimeout),
359 0x12 => Some(SessionErrorCode::DataStreamTimeout),
360 0x13 => Some(SessionErrorCode::AuthTokenCacheOverflow),
361 0x14 => Some(SessionErrorCode::DuplicateAuthTokenAlias),
362 0x15 => Some(SessionErrorCode::VersionNegotiationFailed),
363 0x16 => Some(SessionErrorCode::MalformedAuthToken),
364 0x17 => Some(SessionErrorCode::UnknownAuthTokenAlias),
365 0x18 => Some(SessionErrorCode::ExpiredAuthToken),
366 _ => None,
367 }
368 }
369
370 /// Return the raw u64 value of this error code.
371 pub fn as_u64(self) -> u64 {
372 self as u64
373 }
374}
375
376impl SubscribeErrorCode {
377 /// Every SUBSCRIBE_ERROR code draft-12 assigns, in ascending wire order.
378 ///
379 /// This is the set [`Self::from_u64`] accepts, written out so that it can
380 /// be enumerated: nothing can iterate an enum's variants, so a caller that
381 /// wants the registry has to be handed it. Writing it down is also what
382 /// lets a test state its claims about the registry itself rather than about
383 /// the range some sweep happens to reach.
384 pub const ALL: &[SubscribeErrorCode] = &[
385 SubscribeErrorCode::InternalError,
386 SubscribeErrorCode::Unauthorized,
387 SubscribeErrorCode::Timeout,
388 SubscribeErrorCode::NotSupported,
389 SubscribeErrorCode::TrackDoesNotExist,
390 SubscribeErrorCode::InvalidRange,
391 SubscribeErrorCode::MalformedAuthToken,
392 SubscribeErrorCode::ExpiredAuthToken,
393 ];
394
395 /// Convert a raw u64 to a `SubscribeErrorCode`, if valid.
396 pub fn from_u64(v: u64) -> Option<Self> {
397 match v {
398 0x0 => Some(SubscribeErrorCode::InternalError),
399 0x1 => Some(SubscribeErrorCode::Unauthorized),
400 0x2 => Some(SubscribeErrorCode::Timeout),
401 0x3 => Some(SubscribeErrorCode::NotSupported),
402 0x4 => Some(SubscribeErrorCode::TrackDoesNotExist),
403 0x5 => Some(SubscribeErrorCode::InvalidRange),
404 0x10 => Some(SubscribeErrorCode::MalformedAuthToken),
405 0x12 => Some(SubscribeErrorCode::ExpiredAuthToken),
406 _ => None,
407 }
408 }
409
410 /// Return the raw u64 value of this error code.
411 pub fn as_u64(self) -> u64 {
412 self as u64
413 }
414}
415
416impl SubscribeDoneStatusCode {
417 /// Every SUBSCRIBE_DONE status code draft-12 assigns, in ascending wire order.
418 ///
419 /// This is the set [`Self::from_u64`] accepts, written out so that it can
420 /// be enumerated: nothing can iterate an enum's variants, so a caller that
421 /// wants the registry has to be handed it. Writing it down is also what
422 /// lets a test state its claims about the registry itself rather than about
423 /// the range some sweep happens to reach.
424 pub const ALL: &[SubscribeDoneStatusCode] = &[
425 SubscribeDoneStatusCode::InternalError,
426 SubscribeDoneStatusCode::Unauthorized,
427 SubscribeDoneStatusCode::TrackEnded,
428 SubscribeDoneStatusCode::SubscriptionEnded,
429 SubscribeDoneStatusCode::GoingAway,
430 SubscribeDoneStatusCode::Expired,
431 SubscribeDoneStatusCode::TooFarBehind,
432 SubscribeDoneStatusCode::MalformedTrack,
433 ];
434
435 /// Convert a raw u64 to a `SubscribeDoneStatusCode`, if valid.
436 pub fn from_u64(v: u64) -> Option<Self> {
437 match v {
438 0x0 => Some(SubscribeDoneStatusCode::InternalError),
439 0x1 => Some(SubscribeDoneStatusCode::Unauthorized),
440 0x2 => Some(SubscribeDoneStatusCode::TrackEnded),
441 0x3 => Some(SubscribeDoneStatusCode::SubscriptionEnded),
442 0x4 => Some(SubscribeDoneStatusCode::GoingAway),
443 0x5 => Some(SubscribeDoneStatusCode::Expired),
444 0x6 => Some(SubscribeDoneStatusCode::TooFarBehind),
445 0x7 => Some(SubscribeDoneStatusCode::MalformedTrack),
446 _ => None,
447 }
448 }
449
450 /// Return the raw u64 value of this status code.
451 pub fn as_u64(self) -> u64 {
452 self as u64
453 }
454}
455
456impl PublishErrorCode {
457 /// Every PUBLISH_ERROR code draft-12 assigns, in ascending wire order.
458 ///
459 /// This is the set [`Self::from_u64`] accepts, written out so that it can
460 /// be enumerated: nothing can iterate an enum's variants, so a caller that
461 /// wants the registry has to be handed it. Writing it down is also what
462 /// lets a test state its claims about the registry itself rather than about
463 /// the range some sweep happens to reach.
464 pub const ALL: &[PublishErrorCode] = &[
465 PublishErrorCode::InternalError,
466 PublishErrorCode::Unauthorized,
467 PublishErrorCode::Timeout,
468 PublishErrorCode::NotSupported,
469 PublishErrorCode::Uninterested,
470 ];
471
472 /// Convert a raw u64 to a `PublishErrorCode`, if valid.
473 pub fn from_u64(v: u64) -> Option<Self> {
474 match v {
475 0x0 => Some(PublishErrorCode::InternalError),
476 0x1 => Some(PublishErrorCode::Unauthorized),
477 0x2 => Some(PublishErrorCode::Timeout),
478 0x3 => Some(PublishErrorCode::NotSupported),
479 0x4 => Some(PublishErrorCode::Uninterested),
480 _ => None,
481 }
482 }
483
484 /// Return the raw u64 value of this error code.
485 pub fn as_u64(self) -> u64 {
486 self as u64
487 }
488}
489
490impl FetchErrorCode {
491 /// Every FETCH_ERROR code draft-12 assigns, in ascending wire order.
492 ///
493 /// This is the set [`Self::from_u64`] accepts, written out so that it can
494 /// be enumerated: nothing can iterate an enum's variants, so a caller that
495 /// wants the registry has to be handed it. Writing it down is also what
496 /// lets a test state its claims about the registry itself rather than about
497 /// the range some sweep happens to reach.
498 pub const ALL: &[FetchErrorCode] = &[
499 FetchErrorCode::InternalError,
500 FetchErrorCode::Unauthorized,
501 FetchErrorCode::Timeout,
502 FetchErrorCode::NotSupported,
503 FetchErrorCode::TrackDoesNotExist,
504 FetchErrorCode::InvalidRange,
505 FetchErrorCode::NoObjects,
506 FetchErrorCode::InvalidJoiningRequestId,
507 FetchErrorCode::UnknownStatusInRange,
508 FetchErrorCode::MalformedTrack,
509 FetchErrorCode::MalformedAuthToken,
510 FetchErrorCode::ExpiredAuthToken,
511 ];
512
513 /// Convert a raw u64 to a `FetchErrorCode`, if valid.
514 pub fn from_u64(v: u64) -> Option<Self> {
515 match v {
516 0x0 => Some(FetchErrorCode::InternalError),
517 0x1 => Some(FetchErrorCode::Unauthorized),
518 0x2 => Some(FetchErrorCode::Timeout),
519 0x3 => Some(FetchErrorCode::NotSupported),
520 0x4 => Some(FetchErrorCode::TrackDoesNotExist),
521 0x5 => Some(FetchErrorCode::InvalidRange),
522 0x6 => Some(FetchErrorCode::NoObjects),
523 0x7 => Some(FetchErrorCode::InvalidJoiningRequestId),
524 0x8 => Some(FetchErrorCode::UnknownStatusInRange),
525 0x9 => Some(FetchErrorCode::MalformedTrack),
526 0x10 => Some(FetchErrorCode::MalformedAuthToken),
527 0x12 => Some(FetchErrorCode::ExpiredAuthToken),
528 _ => None,
529 }
530 }
531
532 /// Return the raw u64 value of this error code.
533 pub fn as_u64(self) -> u64 {
534 self as u64
535 }
536}
537
538impl AnnounceErrorCode {
539 /// Every ANNOUNCE_ERROR code draft-12 assigns, in ascending wire order.
540 ///
541 /// This is the set [`Self::from_u64`] accepts, written out so that it can
542 /// be enumerated: nothing can iterate an enum's variants, so a caller that
543 /// wants the registry has to be handed it. Writing it down is also what
544 /// lets a test state its claims about the registry itself rather than about
545 /// the range some sweep happens to reach.
546 pub const ALL: &[AnnounceErrorCode] = &[
547 AnnounceErrorCode::InternalError,
548 AnnounceErrorCode::Unauthorized,
549 AnnounceErrorCode::Timeout,
550 AnnounceErrorCode::NotSupported,
551 AnnounceErrorCode::Uninterested,
552 AnnounceErrorCode::MalformedAuthToken,
553 AnnounceErrorCode::ExpiredAuthToken,
554 ];
555
556 /// Convert a raw u64 to an `AnnounceErrorCode`, if valid.
557 pub fn from_u64(v: u64) -> Option<Self> {
558 match v {
559 0x0 => Some(AnnounceErrorCode::InternalError),
560 0x1 => Some(AnnounceErrorCode::Unauthorized),
561 0x2 => Some(AnnounceErrorCode::Timeout),
562 0x3 => Some(AnnounceErrorCode::NotSupported),
563 0x4 => Some(AnnounceErrorCode::Uninterested),
564 0x10 => Some(AnnounceErrorCode::MalformedAuthToken),
565 0x12 => Some(AnnounceErrorCode::ExpiredAuthToken),
566 _ => None,
567 }
568 }
569
570 /// Return the raw u64 value of this error code.
571 pub fn as_u64(self) -> u64 {
572 self as u64
573 }
574}
575
576impl SubscribeAnnouncesErrorCode {
577 /// Every SUBSCRIBE_ANNOUNCES_ERROR code draft-12 assigns, in ascending wire order.
578 ///
579 /// This is the set [`Self::from_u64`] accepts, written out so that it can
580 /// be enumerated: nothing can iterate an enum's variants, so a caller that
581 /// wants the registry has to be handed it. Writing it down is also what
582 /// lets a test state its claims about the registry itself rather than about
583 /// the range some sweep happens to reach.
584 pub const ALL: &[SubscribeAnnouncesErrorCode] = &[
585 SubscribeAnnouncesErrorCode::InternalError,
586 SubscribeAnnouncesErrorCode::Unauthorized,
587 SubscribeAnnouncesErrorCode::Timeout,
588 SubscribeAnnouncesErrorCode::NotSupported,
589 SubscribeAnnouncesErrorCode::NamespacePrefixUnknown,
590 SubscribeAnnouncesErrorCode::NamespacePrefixOverlap,
591 SubscribeAnnouncesErrorCode::MalformedAuthToken,
592 SubscribeAnnouncesErrorCode::ExpiredAuthToken,
593 ];
594
595 /// Convert a raw u64 to a `SubscribeAnnouncesErrorCode`, if valid.
596 pub fn from_u64(v: u64) -> Option<Self> {
597 match v {
598 0x0 => Some(SubscribeAnnouncesErrorCode::InternalError),
599 0x1 => Some(SubscribeAnnouncesErrorCode::Unauthorized),
600 0x2 => Some(SubscribeAnnouncesErrorCode::Timeout),
601 0x3 => Some(SubscribeAnnouncesErrorCode::NotSupported),
602 0x4 => Some(SubscribeAnnouncesErrorCode::NamespacePrefixUnknown),
603 0x5 => Some(SubscribeAnnouncesErrorCode::NamespacePrefixOverlap),
604 0x10 => Some(SubscribeAnnouncesErrorCode::MalformedAuthToken),
605 0x12 => Some(SubscribeAnnouncesErrorCode::ExpiredAuthToken),
606 _ => None,
607 }
608 }
609
610 /// Return the raw u64 value of this error code.
611 pub fn as_u64(self) -> u64 {
612 self as u64
613 }
614}
615
616impl StreamResetErrorCode {
617 /// Every subgroup stream reset code draft-12 assigns, in ascending wire order.
618 ///
619 /// This is the set [`Self::from_u64`] accepts, written out so that it can
620 /// be enumerated: nothing can iterate an enum's variants, so a caller that
621 /// wants the registry has to be handed it. Writing it down is also what
622 /// lets a test state its claims about the registry itself rather than about
623 /// the range some sweep happens to reach.
624 pub const ALL: &[StreamResetErrorCode] = &[
625 StreamResetErrorCode::InternalError,
626 StreamResetErrorCode::Cancelled,
627 StreamResetErrorCode::DeliveryTimeout,
628 StreamResetErrorCode::SessionClosed,
629 ];
630
631 /// Convert a raw u64 to a `StreamResetErrorCode`, if valid.
632 pub fn from_u64(v: u64) -> Option<Self> {
633 match v {
634 0x0 => Some(StreamResetErrorCode::InternalError),
635 0x1 => Some(StreamResetErrorCode::Cancelled),
636 0x2 => Some(StreamResetErrorCode::DeliveryTimeout),
637 0x3 => Some(StreamResetErrorCode::SessionClosed),
638 _ => None,
639 }
640 }
641
642 /// Return the raw u64 value of this error code.
643 pub fn as_u64(self) -> u64 {
644 self as u64
645 }
646}
647
648/// TRACK_STATUS Status Code values (draft-12, Section 8.21).
649///
650/// The draft defines these as a prose list rather than as a `Code`/`Reason`
651/// table, so they are named from the prose. It is stricter about this field
652/// than about the error registries above: the Status Code "MUST hold one of the
653/// following values" and "Any other value in the Status Code field is a
654/// malformed message", so [`TrackStatusCode::from_u64`] answering `None` is a
655/// decode failure rather than a merely unrecognised code.
656#[derive(Debug, Clone, Copy, PartialEq, Eq)]
657#[repr(u64)]
658pub enum TrackStatusCode {
659 /// The track is in progress, and subsequent fields contain the highest
660 /// group and object ID for that track.
661 InProgress = 0x00,
662 /// The track does not exist. Subsequent fields MUST be zero, and any other
663 /// value is a malformed message.
664 TrackDoesNotExist = 0x01,
665 /// The track has not yet begun. Subsequent fields MUST be zero, and any
666 /// other value is a malformed message.
667 NotYetBegun = 0x02,
668 /// The track has finished, so there is no live edge. Subsequent fields
669 /// contain the highest group and object ID known.
670 Finished = 0x03,
671 /// The publisher is a relay that cannot obtain the current track status
672 /// from upstream. Subsequent fields contain the largest group and object
673 /// ID known.
674 RelayStatusUnavailable = 0x04,
675}
676
677impl TrackStatusCode {
678 /// Convert a raw u64 to a `TrackStatusCode`, if this draft assigns it.
679 pub fn from_u64(v: u64) -> Option<Self> {
680 match v {
681 0x00 => Some(TrackStatusCode::InProgress),
682 0x01 => Some(TrackStatusCode::TrackDoesNotExist),
683 0x02 => Some(TrackStatusCode::NotYetBegun),
684 0x03 => Some(TrackStatusCode::Finished),
685 0x04 => Some(TrackStatusCode::RelayStatusUnavailable),
686 _ => None,
687 }
688 }
689
690 /// Whether this code requires the fields after it to be zero.
691 ///
692 /// Section 8.21 says of 0x01 "Subsequent fields MUST be zero, and any other
693 /// value is a malformed message", and the same of 0x02. The other three
694 /// codes describe those fields as carrying a real location, so they place
695 /// no requirement on them.
696 pub fn requires_zero_location(self) -> bool {
697 matches!(self, TrackStatusCode::TrackDoesNotExist | TrackStatusCode::NotYetBegun)
698 }
699
700 /// Return the raw u64 value of this status code.
701 pub fn as_u64(self) -> u64 {
702 self as u64
703 }
704}