Skip to main content

moqtap_codec/draft13/
error_codes.rs

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