Skip to main content

DecodeError

Enum DecodeError 

Source
#[non_exhaustive]
pub enum DecodeError { Truncated, BadMagic, BadVersion(u8), BadTag, BadGeometry, BadSpan, }
Expand description

Why a byte buffer could not be decoded into a Frame.

#[non_exhaustive] (#843). A decode error is displayed, never branched on for correctness, so a new variant is one a consumer can safely fall through on. See the BadScroll note on DecodeError::BadGeometry — this attribute is what changes that trade.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Truncated

Ran out of bytes mid-field.

§

BadMagic

First two bytes are not the wire magic.

§

BadVersion(u8)

Unsupported format version.

§

BadTag

A tag/kind byte held a value outside its defined set.

§

BadGeometry

The frame’s own declared geometry is one no terminal can have: fewer than MIN_COLUMNS columns, or no rows at all (#663).

Distinct from BadSpan, and the distinction is the direction of the comparison rather than a shade of severity. BadSpan means a part of the frame does not fit the geometry the header declares; this means the header itself declares a geometry the engine defines as impossible and clamps away at every entry point (Term::with_scrollback and Term::resize widen cols to MIN_COLUMNS and rows to 1). Nothing this crate encodes can carry it, so it is malformed input by the same rule BadSpan applies one level in.

The floor imports no policy: xterm.js clamps to the same pair for the same reason (MINIMUM_COLS = 2, “Less than 2 can mess with wide chars”, and MINIMUM_ROWS = 1). There is deliberately no ceiling error — cols/rows are u16 on the wire and MAX_COLUMNS is u16::MAX for exactly that reason, so the upper end is bounded by the field and needs no check.

This variant is what BadSpan’s doc-comment deferred to “the next release that is breaking anyway” — #663 changes what decode accepts, so the version that carries it is that release, and the marginal cost of the enum growing is paid there rather than on its own. Measured at the time: no exhaustive match on DecodeError exists in this workspace, justerm-wasm-decode formats the variant with {:?} (so the name reaches JS unaided, #662), and penterm holds no reference to the type.

§

BadSpan

A part of the frame does not fit the geometry the frame itself declares: a span whose left is past its right (which would underflow the cell count), a span reaching past cols or sitting past rows, a sparse group entry keyed outside its own span, or a scroll region whose bottom is past the last row (#582).

One rule, one error: a coordinate describing a cell the frame says does not exist is malformed input, and the consumer must not be handed it.

A dedicated BadScroll was considered and not taken, and the trade is worth stating honestly rather than as a slogan. Against it: this enum is pub and not #[non_exhaustive], so a new variant is a breaking change for any downstream exhaustive match — of which there are, measured, none in this workspace; the cost is borne only by an external matcher nobody has seen. For it: this variant is now the whole diagnostic for six distinct malformations, and the JS side has no more to work with (justerm-wasm-decode formats the variant name into the thrown Error’s message, #662). The distinction is real but belongs to the next release that is breaking anyway — a version bump spent on a diagnostic label, on a crate published in lockstep with an npm package, is the more expensive half of this trade today.

That condition arrived, and only for the case it names (#663). BadGeometry split off because #663 changes what decode accepts, so its release is the breaking one this paragraph was waiting for. It is not a precedent for splitting the six below: the new variant answers a comparison pointing the other way (the header against the engine, not a part against the header), whereas BadScroll would still be one of these six re-labelled. The trade above is unchanged for them and they stay merged.

And the against half of that trade is now void (#843). The paragraph rests on this enum being pub and not #[non_exhaustive], which stopped being true when the attribute landed on it: a seventh variant is no longer a breaking change for a Rust consumer, so splitting BadScroll off no longer has to wait for a release that is breaking for some other reason.

The qualifier is not pedantry. The variant name is a cross-language contract — ADR-0008 has justerm-wasm-decode throw it as the JS Error message — and #[non_exhaustive] does nothing for that consumer. (It is already approximate there, since BadVersion(11) formats as more than a name.) The ecosystem vote points the same way for this type specifically: among justerm’s own dependencies, regex and regex-syntax mark error types non-exhaustive with that reason spelled out, while vte — a published, semver’d VT crate in the same domain — marks none of its 17 public enums. Errors yes, domain enums no, which is the line this sweep drew before the vote was counted.

What survives is the for half — whether six malformations deserve six labels — and that is a diagnostics question to answer on its merits, with the version-bump argument removed from the scale rather than answered.

The paragraphs above are deliberately not rewritten. They record what was decided and on what, and a reader who cannot see the old grounds cannot tell that the conclusion outlived them.

Trait Implementations§

Source§

impl Clone for DecodeError

Source§

fn clone(&self) -> DecodeError

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for DecodeError

Source§

impl Debug for DecodeError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for DecodeError

Source§

impl PartialEq for DecodeError

Source§

fn eq(&self, other: &DecodeError) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for DecodeError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.