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