moqtap_codec/draft19/error_codes.rs
1//! Error, status and stream-reset code registries defined by
2//! draft-ietf-moq-transport-19.
3//!
4//! One enum per registry in the IANA Considerations section (Section 15.11). The
5//! registry tables list only Name, Code and Specification; the per-code prose in
6//! the variant docs is taken from the section each row cites.
7//!
8//! `from_u64` returns `None` for any value the draft does not assign. A peer may
9//! legitimately send a code from a later draft or a private extension, and an
10//! unrecognized code must not be a decode failure at this layer.
11//!
12//! Each of these four registries reserves `0x7f * N + 0x9D` for greasing
13//! (Section 14). That is a range rather than an assignment, so it gets no
14//! variant and `from_u64` reports it as unknown like any other unassigned value.
15//!
16//! Code points inside a registry are not contiguous; the gaps are the draft's.
17
18/// Session termination error codes (draft-19 Section 15.11.1).
19///
20/// Sent as the error code when closing the Transport Session: the QUIC `CONNECTION_CLOSE` frame
21/// over native QUIC, or the `CLOSE_WEBTRANSPORT_SESSION` capsule over WebTransport. The per-code
22/// definitions are in Section 3.5 of the draft. Note that this draft assigns no code point 0x7,
23/// and none in 0xA-0xF. 0x7 was last assigned by draft-17, as `INVALID_REQUIRED_REQUEST_ID`;
24/// drafts 14 through 16 used it for `TOO_MANY_REQUESTS`. Draft-18 vacated it and draft-19 leaves
25/// it vacant.
26///
27/// The registry also reserves the code points `0x7f * N + 0x9D` for greasing (draft-19 Section
28/// 14). That is a range rather than an assignment, so it has no variant here and `from_u64`
29/// reports it as unknown.
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31#[repr(u64)]
32pub enum SessionErrorCode {
33 /// `NO_ERROR` — The session is being terminated without an error.
34 NoError = 0x0,
35
36 /// `INTERNAL_ERROR` — An implementation specific error occurred.
37 InternalError = 0x1,
38
39 /// `UNAUTHORIZED` — The client is not authorized to establish a session.
40 Unauthorized = 0x2,
41
42 /// `PROTOCOL_VIOLATION` — The remote endpoint performed an action that was disallowed by the
43 /// specification.
44 ProtocolViolation = 0x3,
45
46 /// `INVALID_REQUEST_ID` — The endpoint received a Request ID with an incorrect least
47 /// significant bit for the sender, or a duplicate Request ID. See Section 10.1.
48 InvalidRequestId = 0x4,
49
50 /// `DUPLICATE_TRACK_ALIAS` — The endpoint attempted to use a Track Alias that was already in
51 /// use.
52 DuplicateTrackAlias = 0x5,
53
54 /// `KEY_VALUE_FORMATTING_ERROR` — The key-value pair has a formatting error.
55 KeyValueFormattingError = 0x6,
56
57 /// `INVALID_PATH` — The PATH parameter was used by a server, on a WebTransport session, or
58 /// the server does not support the path.
59 InvalidPath = 0x8,
60
61 /// `MALFORMED_PATH` — The PATH parameter does not conform to the rules in Section 10.3.1.2.
62 MalformedPath = 0x9,
63
64 /// `GOAWAY_TIMEOUT` — The session was closed because the peer took too long to close the
65 /// session in response to a GOAWAY (Section 10.4) message. See session migration (Section
66 /// 3.6).
67 GoawayTimeout = 0x10,
68
69 /// `CONTROL_MESSAGE_TIMEOUT` — The session was closed because the peer took too long to
70 /// respond to a control message.
71 ControlMessageTimeout = 0x11,
72
73 /// `DATA_STREAM_TIMEOUT` — The session was closed because the peer took too long to send data
74 /// expected on an open Data Stream (see Section 11). This includes fields of a stream header
75 /// or an object header within a data stream. If an endpoint times out waiting for a new
76 /// object header on an open subgroup stream, it MAY send a STOP_SENDING on that stream or
77 /// terminate the subscription.
78 DataStreamTimeout = 0x12,
79
80 /// `AUTH_TOKEN_CACHE_OVERFLOW` — The Session limit Section 10.3.1.3 of the size of all
81 /// registered Authorization tokens has been exceeded.
82 AuthTokenCacheOverflow = 0x13,
83
84 /// `DUPLICATE_AUTH_TOKEN_ALIAS` — Authorization Token attempted to register an Alias that was
85 /// in use (see Section 10.2.2).
86 DuplicateAuthTokenAlias = 0x14,
87
88 /// `VERSION_NEGOTIATION_FAILED` — The client didn't offer a version supported by the server.
89 VersionNegotiationFailed = 0x15,
90
91 /// `MALFORMED_AUTH_TOKEN` — Invalid Auth Token serialization during registration (see Section
92 /// 10.2.2).
93 MalformedAuthToken = 0x16,
94
95 /// `UNKNOWN_AUTH_TOKEN_ALIAS` — No registered token found for the provided Alias (see Section
96 /// 10.2.2).
97 UnknownAuthTokenAlias = 0x17,
98
99 /// `EXPIRED_AUTH_TOKEN` — Authorization token has expired (Section 10.2.2).
100 ExpiredAuthToken = 0x18,
101
102 /// `INVALID_AUTHORITY` — The specified AUTHORITY does not correspond to this server or cannot
103 /// be used in this context.
104 InvalidAuthority = 0x19,
105
106 /// `MALFORMED_AUTHORITY` — The AUTHORITY value is syntactically invalid.
107 MalformedAuthority = 0x1A,
108
109 /// `TOO_MANY_REQUEST_UPDATES` — The endpoint received a REQUEST_UPDATE that exceeded the
110 /// per-stream limit communicated via the MAX_REQUEST_UPDATES Setup Option (Section 10.3.1.7).
111 TooManyRequestUpdates = 0x1B,
112}
113
114/// REQUEST_ERROR codes (draft-19 Section 15.11.2).
115///
116/// Section 10.6 states that REQUEST_ERROR is sent in response to any request: SUBSCRIBE, FETCH,
117/// PUBLISH, SUBSCRIBE_NAMESPACE, SUBSCRIBE_TRACKS, PUBLISH_NAMESPACE, TRACK_STATUS and
118/// REQUEST_UPDATE. The per-code definitions are in Section 10.6.2, which the registry table cites
119/// as Section 10.6.
120///
121/// Note that the shorter list naming only the first seven of those messages belongs to the
122/// `REDIRECT` code specifically, not to the registry as a whole.
123///
124/// The registry also reserves the code points `0x7f * N + 0x9D` for greasing (draft-19 Section
125/// 14). That is a range rather than an assignment, so it has no variant here and `from_u64`
126/// reports it as unknown.
127#[derive(Debug, Clone, Copy, PartialEq, Eq)]
128#[repr(u64)]
129pub enum RequestErrorCode {
130 /// `INTERNAL_ERROR` — An implementation specific or generic error occurred.
131 InternalError = 0x0,
132
133 /// `UNAUTHORIZED` — The subscriber is not authorized to perform the requested action on the
134 /// given track. This might be retryable if the authorization token is not yet valid.
135 Unauthorized = 0x1,
136
137 /// `TIMEOUT` — The subscription could not be completed before an implementation specific
138 /// timeout. For example, a relay could not establish an upstream subscription within the
139 /// timeout.
140 Timeout = 0x2,
141
142 /// `NOT_SUPPORTED` — The endpoint does not support the type of request.
143 NotSupported = 0x3,
144
145 /// `MALFORMED_AUTH_TOKEN` — Invalid Auth Token serialization during registration (see Section
146 /// 10.2.2).
147 MalformedAuthToken = 0x4,
148
149 /// `EXPIRED_AUTH_TOKEN` — Authorization token has expired (Section 10.2.2).
150 ExpiredAuthToken = 0x5,
151
152 /// `GOING_AWAY` — The endpoint has received a GOAWAY and MAY reject new requests.
153 GoingAway = 0x6,
154
155 /// `EXCESSIVE_LOAD` — The responder is overloaded and cannot process the request at this
156 /// time. The sender SHOULD use the Retry Interval to indicate when the request can be
157 /// retried.
158 ExcessiveLoad = 0x9,
159
160 /// `DOES_NOT_EXIST` — The track or namespace is not available at the publisher.
161 DoesNotExist = 0x10,
162
163 /// `INVALID_RANGE` — In response to SUBSCRIBE or FETCH, specified Filter or range of
164 /// Locations cannot be satisfied.
165 InvalidRange = 0x11,
166
167 /// `MALFORMED_TRACK` — In response to a FETCH, a relay publisher detected the track was
168 /// malformed (see Section 2.4.2).
169 MalformedTrack = 0x12,
170
171 /// `UNINTERESTED` — The subscriber is not interested in the track or namespace.
172 Uninterested = 0x20,
173
174 /// `PREFIX_OVERLAP` — In response to SUBSCRIBE_NAMESPACE or SUBSCRIBE_TRACKS, the namespace
175 /// prefix shares a common prefix with another subscription of the same type in the same
176 /// session. SUBSCRIBE_NAMESPACE and SUBSCRIBE_TRACKS have independent overlap spaces, so a
177 /// SUBSCRIBE_NAMESPACE and a SUBSCRIBE_TRACKS may share the same prefix.
178 PrefixOverlap = 0x30,
179
180 /// `NAMESPACE_TOO_LARGE` — In response to SUBSCRIBE_NAMESPACE or SUBSCRIBE_TRACKS, the
181 /// namespace prefix matches more publishers than the relay is willing to enumerate.
182 NamespaceTooLarge = 0x31,
183
184 /// `INVALID_JOINING_REQUEST_ID` — In response to a Joining FETCH, the referenced Request ID
185 /// is not an Established Subscription.
186 InvalidJoiningRequestId = 0x32,
187
188 /// `UNSUPPORTED_EXTENSION` — The track contains a Mandatory Track Property (see Section
189 /// 2.5.1) that the endpoint does not understand.
190 UnsupportedExtension = 0x33,
191
192 /// `REDIRECT` — The request cannot be fulfilled by this endpoint, but could succeed at the
193 /// location specified in the Redirect structure. The requester SHOULD establish a new session
194 /// to the provided URI (if present) and retry the request using the Full Track Name from the
195 /// Redirect (if present). This error code can appear in response to SUBSCRIBE, FETCH,
196 /// TRACK_STATUS, PUBLISH, PUBLISH_NAMESPACE, SUBSCRIBE_NAMESPACE, and SUBSCRIBE_TRACKS.
197 /// Relays are not required to follow redirects from upstream and MAY forward a REDIRECT
198 /// response to matching downstream requests. A relay MAY cache a REDIRECT response for a Full
199 /// Track Name for up to Retry Interval milliseconds and use it to respond to subsequent
200 /// matching requests without forwarding them upstream.
201 Redirect = 0x34,
202
203 /// `CONFLICTING_FILTERS` — In response to SUBSCRIBE_TRACKS, the filter parameters conflict
204 /// among too many subscribers to aggregate the subscription upstream or otherwise efficiently
205 /// service it.
206 ConflictingFilters = 0x35,
207
208 /// `INVALID_FILTER` — A filter parameter is invalid.
209 InvalidFilter = 0x36,
210}
211
212/// PUBLISH_DONE codes (draft-19 Section 15.11.3).
213///
214/// Carried in the Status Code field of PUBLISH_DONE. The per-code definitions are in Section
215/// 10.11 of the draft.
216///
217/// The registry also reserves the code points `0x7f * N + 0x9D` for greasing (draft-19 Section
218/// 14). That is a range rather than an assignment, so it has no variant here and `from_u64`
219/// reports it as unknown.
220#[derive(Debug, Clone, Copy, PartialEq, Eq)]
221#[repr(u64)]
222pub enum PublishDoneStatusCode {
223 /// `INTERNAL_ERROR` — An implementation specific or generic error occurred.
224 InternalError = 0x0,
225
226 /// `UNAUTHORIZED` — The subscriber is no longer authorized to subscribe to the given track.
227 Unauthorized = 0x1,
228
229 /// `TRACK_ENDED` — The track is no longer being published.
230 TrackEnded = 0x2,
231
232 /// `SUBSCRIPTION_ENDED` — The publisher reached the end of an associated location filter.
233 SubscriptionEnded = 0x3,
234
235 /// `GOING_AWAY` — The subscriber or publisher issued a GOAWAY message.
236 GoingAway = 0x4,
237
238 /// `TOO_FAR_BEHIND` — The publisher's queue of objects to be sent to the given subscriber
239 /// exceeds its implementation defined limit.
240 TooFarBehind = 0x5,
241
242 /// `EXPIRED` — The publisher reached the timeout specified in SUBSCRIBE_OK.
243 Expired = 0x6,
244
245 /// `UPDATE_FAILED` — REQUEST_UPDATE failed on this subscription (see Section 10.9).
246 UpdateFailed = 0x8,
247
248 /// `EXCESSIVE_LOAD` — The publisher is overloaded and is terminating the subscription.
249 ExcessiveLoad = 0x9,
250
251 /// `MALFORMED_TRACK` — A relay publisher detected that the track was malformed (see Section
252 /// 2.4.2).
253 MalformedTrack = 0x12,
254}
255
256/// Stream reset error codes (draft-19 Section 15.11.4).
257///
258/// Section 3.3.4 says the application SHOULD use a relevant code from this registry when
259/// resetting, or sending STOP_SENDING on, any stream — data streams and request streams alike.
260/// The per-code definitions are in that same section.
261///
262/// Drafts 14 through 17, draft-17 Section 14.5.4 among them, titled this
263/// registry "Data Stream Reset Error Codes" and this crate names those drafts'
264/// enums `DataStreamResetErrorCode`. Draft-18 renamed it and widened it beyond
265/// data streams; draft-19 keeps both the name and the wider scope, so this enum
266/// takes that title.
267///
268/// The registry also reserves the code points `0x7f * N + 0x9D` for greasing (draft-19 Section
269/// 14). That is a range rather than an assignment, so it has no variant here and `from_u64`
270/// reports it as unknown.
271#[derive(Debug, Clone, Copy, PartialEq, Eq)]
272#[repr(u64)]
273pub enum StreamResetErrorCode {
274 /// `INTERNAL_ERROR` — An implementation specific error.
275 InternalError = 0x0,
276
277 /// `CANCELLED` — The stream was cancelled by either endpoint. For Subscriptions, PUBLISH_DONE
278 /// (Section 10.11) may have a more detailed status code.
279 Cancelled = 0x1,
280
281 /// `DELIVERY_TIMEOUT` — A delivery timeout (Section 8) was exceeded for this stream.
282 DeliveryTimeout = 0x2,
283
284 /// `SESSION_CLOSED` — The session is being closed.
285 SessionClosed = 0x3,
286
287 /// `GOING_AWAY` — The endpoint is rejecting this request because it has sent or received a
288 /// GOAWAY.
289 GoingAway = 0x4,
290
291 /// `TOO_FAR_BEHIND` — The corresponding subscription has exceeded the publisher's resource
292 /// limits and is being terminated (see Section 8).
293 TooFarBehind = 0x5,
294
295 /// `UNKNOWN_OBJECT_STATUS` — In response to a FETCH, the publisher is unable to determine the
296 /// status of the next Object in the requested range.
297 UnknownObjectStatus = 0x6,
298
299 /// `EXPIRED_AUTH_TOKEN` — The authorization token for the request has expired.
300 ExpiredAuthToken = 0x7,
301
302 /// `EXCESSIVE_LOAD` — The endpoint is overloaded and is resetting this stream.
303 ExcessiveLoad = 0x9,
304
305 /// `MALFORMED_TRACK` — A relay publisher detected that the track was malformed (see Section
306 /// 2.4.2).
307 MalformedTrack = 0x12,
308}
309
310impl SessionErrorCode {
311 /// Every Session Error Code draft-19 assigns, in ascending wire order.
312 ///
313 /// This is the set [`Self::from_u64`] accepts, written out so that it can
314 /// be enumerated: nothing can iterate an enum's variants, so a caller that
315 /// wants the registry has to be handed it. Writing it down is also what
316 /// lets a test state its claims about the registry itself rather than about
317 /// the range some sweep happens to reach — that this is the set `from_u64`
318 /// answers to, and that none of it lands in the range the draft reserves
319 /// for greasing.
320 pub const ALL: &[SessionErrorCode] = &[
321 SessionErrorCode::NoError,
322 SessionErrorCode::InternalError,
323 SessionErrorCode::Unauthorized,
324 SessionErrorCode::ProtocolViolation,
325 SessionErrorCode::InvalidRequestId,
326 SessionErrorCode::DuplicateTrackAlias,
327 SessionErrorCode::KeyValueFormattingError,
328 SessionErrorCode::InvalidPath,
329 SessionErrorCode::MalformedPath,
330 SessionErrorCode::GoawayTimeout,
331 SessionErrorCode::ControlMessageTimeout,
332 SessionErrorCode::DataStreamTimeout,
333 SessionErrorCode::AuthTokenCacheOverflow,
334 SessionErrorCode::DuplicateAuthTokenAlias,
335 SessionErrorCode::VersionNegotiationFailed,
336 SessionErrorCode::MalformedAuthToken,
337 SessionErrorCode::UnknownAuthTokenAlias,
338 SessionErrorCode::ExpiredAuthToken,
339 SessionErrorCode::InvalidAuthority,
340 SessionErrorCode::MalformedAuthority,
341 SessionErrorCode::TooManyRequestUpdates,
342 ];
343
344 /// Convert a raw u64 to a `SessionErrorCode`, if the draft assigns that code point.
345 ///
346 /// Returns `None` for any unassigned value, including the greasing range, so
347 /// that a peer sending a code this draft does not define cannot break decoding.
348 pub fn from_u64(v: u64) -> Option<Self> {
349 match v {
350 0x0 => Some(SessionErrorCode::NoError),
351 0x1 => Some(SessionErrorCode::InternalError),
352 0x2 => Some(SessionErrorCode::Unauthorized),
353 0x3 => Some(SessionErrorCode::ProtocolViolation),
354 0x4 => Some(SessionErrorCode::InvalidRequestId),
355 0x5 => Some(SessionErrorCode::DuplicateTrackAlias),
356 0x6 => Some(SessionErrorCode::KeyValueFormattingError),
357 0x8 => Some(SessionErrorCode::InvalidPath),
358 0x9 => Some(SessionErrorCode::MalformedPath),
359 0x10 => Some(SessionErrorCode::GoawayTimeout),
360 0x11 => Some(SessionErrorCode::ControlMessageTimeout),
361 0x12 => Some(SessionErrorCode::DataStreamTimeout),
362 0x13 => Some(SessionErrorCode::AuthTokenCacheOverflow),
363 0x14 => Some(SessionErrorCode::DuplicateAuthTokenAlias),
364 0x15 => Some(SessionErrorCode::VersionNegotiationFailed),
365 0x16 => Some(SessionErrorCode::MalformedAuthToken),
366 0x17 => Some(SessionErrorCode::UnknownAuthTokenAlias),
367 0x18 => Some(SessionErrorCode::ExpiredAuthToken),
368 0x19 => Some(SessionErrorCode::InvalidAuthority),
369 0x1A => Some(SessionErrorCode::MalformedAuthority),
370 0x1B => Some(SessionErrorCode::TooManyRequestUpdates),
371 _ => None,
372 }
373 }
374
375 /// Return the raw u64 value of this error code.
376 pub fn as_u64(self) -> u64 {
377 self as u64
378 }
379}
380
381impl RequestErrorCode {
382 /// Every Request Error Code draft-19 assigns, in ascending wire order.
383 ///
384 /// This is the set [`Self::from_u64`] accepts, written out so that it can
385 /// be enumerated: nothing can iterate an enum's variants, so a caller that
386 /// wants the registry has to be handed it. Writing it down is also what
387 /// lets a test state its claims about the registry itself rather than about
388 /// the range some sweep happens to reach — that this is the set `from_u64`
389 /// answers to, and that none of it lands in the range the draft reserves
390 /// for greasing.
391 pub const ALL: &[RequestErrorCode] = &[
392 RequestErrorCode::InternalError,
393 RequestErrorCode::Unauthorized,
394 RequestErrorCode::Timeout,
395 RequestErrorCode::NotSupported,
396 RequestErrorCode::MalformedAuthToken,
397 RequestErrorCode::ExpiredAuthToken,
398 RequestErrorCode::GoingAway,
399 RequestErrorCode::ExcessiveLoad,
400 RequestErrorCode::DoesNotExist,
401 RequestErrorCode::InvalidRange,
402 RequestErrorCode::MalformedTrack,
403 RequestErrorCode::Uninterested,
404 RequestErrorCode::PrefixOverlap,
405 RequestErrorCode::NamespaceTooLarge,
406 RequestErrorCode::InvalidJoiningRequestId,
407 RequestErrorCode::UnsupportedExtension,
408 RequestErrorCode::Redirect,
409 RequestErrorCode::ConflictingFilters,
410 RequestErrorCode::InvalidFilter,
411 ];
412
413 /// Convert a raw u64 to a `RequestErrorCode`, if the draft assigns that code point.
414 ///
415 /// Returns `None` for any unassigned value, including the greasing range, so
416 /// that a peer sending a code this draft does not define cannot break decoding.
417 pub fn from_u64(v: u64) -> Option<Self> {
418 match v {
419 0x0 => Some(RequestErrorCode::InternalError),
420 0x1 => Some(RequestErrorCode::Unauthorized),
421 0x2 => Some(RequestErrorCode::Timeout),
422 0x3 => Some(RequestErrorCode::NotSupported),
423 0x4 => Some(RequestErrorCode::MalformedAuthToken),
424 0x5 => Some(RequestErrorCode::ExpiredAuthToken),
425 0x6 => Some(RequestErrorCode::GoingAway),
426 0x9 => Some(RequestErrorCode::ExcessiveLoad),
427 0x10 => Some(RequestErrorCode::DoesNotExist),
428 0x11 => Some(RequestErrorCode::InvalidRange),
429 0x12 => Some(RequestErrorCode::MalformedTrack),
430 0x20 => Some(RequestErrorCode::Uninterested),
431 0x30 => Some(RequestErrorCode::PrefixOverlap),
432 0x31 => Some(RequestErrorCode::NamespaceTooLarge),
433 0x32 => Some(RequestErrorCode::InvalidJoiningRequestId),
434 0x33 => Some(RequestErrorCode::UnsupportedExtension),
435 0x34 => Some(RequestErrorCode::Redirect),
436 0x35 => Some(RequestErrorCode::ConflictingFilters),
437 0x36 => Some(RequestErrorCode::InvalidFilter),
438 _ => None,
439 }
440 }
441
442 /// Return the raw u64 value of this error code.
443 pub fn as_u64(self) -> u64 {
444 self as u64
445 }
446}
447
448impl PublishDoneStatusCode {
449 /// Every PUBLISH_DONE Status Code draft-19 assigns, in ascending wire order.
450 ///
451 /// This is the set [`Self::from_u64`] accepts, written out so that it can
452 /// be enumerated: nothing can iterate an enum's variants, so a caller that
453 /// wants the registry has to be handed it. Writing it down is also what
454 /// lets a test state its claims about the registry itself rather than about
455 /// the range some sweep happens to reach — that this is the set `from_u64`
456 /// answers to, and that none of it lands in the range the draft reserves
457 /// for greasing.
458 pub const ALL: &[PublishDoneStatusCode] = &[
459 PublishDoneStatusCode::InternalError,
460 PublishDoneStatusCode::Unauthorized,
461 PublishDoneStatusCode::TrackEnded,
462 PublishDoneStatusCode::SubscriptionEnded,
463 PublishDoneStatusCode::GoingAway,
464 PublishDoneStatusCode::TooFarBehind,
465 PublishDoneStatusCode::Expired,
466 PublishDoneStatusCode::UpdateFailed,
467 PublishDoneStatusCode::ExcessiveLoad,
468 PublishDoneStatusCode::MalformedTrack,
469 ];
470
471 /// Convert a raw u64 to a `PublishDoneStatusCode`, if the draft assigns that code point.
472 ///
473 /// Returns `None` for any unassigned value, including the greasing range, so
474 /// that a peer sending a code this draft does not define cannot break decoding.
475 pub fn from_u64(v: u64) -> Option<Self> {
476 match v {
477 0x0 => Some(PublishDoneStatusCode::InternalError),
478 0x1 => Some(PublishDoneStatusCode::Unauthorized),
479 0x2 => Some(PublishDoneStatusCode::TrackEnded),
480 0x3 => Some(PublishDoneStatusCode::SubscriptionEnded),
481 0x4 => Some(PublishDoneStatusCode::GoingAway),
482 0x5 => Some(PublishDoneStatusCode::TooFarBehind),
483 0x6 => Some(PublishDoneStatusCode::Expired),
484 0x8 => Some(PublishDoneStatusCode::UpdateFailed),
485 0x9 => Some(PublishDoneStatusCode::ExcessiveLoad),
486 0x12 => Some(PublishDoneStatusCode::MalformedTrack),
487 _ => None,
488 }
489 }
490
491 /// Return the raw u64 value of this status code.
492 pub fn as_u64(self) -> u64 {
493 self as u64
494 }
495}
496
497impl StreamResetErrorCode {
498 /// Every Stream Reset Error Code draft-19 assigns, in ascending wire order.
499 ///
500 /// This is the set [`Self::from_u64`] accepts, written out so that it can
501 /// be enumerated: nothing can iterate an enum's variants, so a caller that
502 /// wants the registry has to be handed it. Writing it down is also what
503 /// lets a test state its claims about the registry itself rather than about
504 /// the range some sweep happens to reach — that this is the set `from_u64`
505 /// answers to, and that none of it lands in the range the draft reserves
506 /// for greasing.
507 pub const ALL: &[StreamResetErrorCode] = &[
508 StreamResetErrorCode::InternalError,
509 StreamResetErrorCode::Cancelled,
510 StreamResetErrorCode::DeliveryTimeout,
511 StreamResetErrorCode::SessionClosed,
512 StreamResetErrorCode::GoingAway,
513 StreamResetErrorCode::TooFarBehind,
514 StreamResetErrorCode::UnknownObjectStatus,
515 StreamResetErrorCode::ExpiredAuthToken,
516 StreamResetErrorCode::ExcessiveLoad,
517 StreamResetErrorCode::MalformedTrack,
518 ];
519
520 /// Convert a raw u64 to a `StreamResetErrorCode`, if the draft assigns that code point.
521 ///
522 /// Returns `None` for any unassigned value, including the greasing range, so
523 /// that a peer sending a code this draft does not define cannot break decoding.
524 pub fn from_u64(v: u64) -> Option<Self> {
525 match v {
526 0x0 => Some(StreamResetErrorCode::InternalError),
527 0x1 => Some(StreamResetErrorCode::Cancelled),
528 0x2 => Some(StreamResetErrorCode::DeliveryTimeout),
529 0x3 => Some(StreamResetErrorCode::SessionClosed),
530 0x4 => Some(StreamResetErrorCode::GoingAway),
531 0x5 => Some(StreamResetErrorCode::TooFarBehind),
532 0x6 => Some(StreamResetErrorCode::UnknownObjectStatus),
533 0x7 => Some(StreamResetErrorCode::ExpiredAuthToken),
534 0x9 => Some(StreamResetErrorCode::ExcessiveLoad),
535 0x12 => Some(StreamResetErrorCode::MalformedTrack),
536 _ => None,
537 }
538 }
539
540 /// Return the raw u64 value of this error code.
541 pub fn as_u64(self) -> u64 {
542 self as u64
543 }
544}