Skip to main content

Reason

Enum Reason 

Source
#[non_exhaustive]
pub enum Reason {
Show 32 variants Syntax(String), NotAForm { found: String, }, Version, FromTheFuture { wanted: u64, understood: u64, }, Missing { kind: String, name: &'static str, }, UnknownWidget { found: String, }, UnknownProperty { kind: &'static str, found: String, accepted: &'static [Property], }, UnknownFormProperty { kind: &'static str, found: String, accepted: Vec<&'static str>, }, WrongType { kind: &'static str, name: String, wanted: &'static str, }, NotAName { name: String, found: String, accepted: &'static [&'static str], }, UnexpectedChild { parent: String, found: String, }, PlaceholderOutside { kind: String, found: String, }, PayloadClash { found: String, first: &'static str, then: &'static str, }, NotAnIdentifier { found: String, because: &'static str, }, Collides { found: String, with: String, spelled: String, }, UnknownMessage { found: String, }, WrongMessage { found: String, wanted: &'static str, }, Asset { path: String, }, DuplicateName { name: String, }, TwoFocuses, TreeRefused, TooDeep { limit: usize, }, TooLarge { limit: usize, }, Unbalanced { open: bool, }, CommentedTooDeep { limit: usize, }, TooSlow { limit: Duration, }, NoThread { abandoned: usize, }, NotPreserved, NoSuchNode { path: Vec<usize>, }, IntoItself { path: Vec<usize>, }, NoArgument, WrongKind { name: String, holds: &'static str, given: &'static str, },
}
Expand description

Everything that can be wrong with a form file.

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.
§

Syntax(String)

The file is not KDL at all.

§

NotAForm

The top level is not a single form node.

Fields

§found: String

What was found there instead.

§

Version

version is missing, or is not a number.

§

FromTheFuture

The file was written for a later version of this crate.

Fields

§wanted: u64

What the file asks for.

§understood: u64

The highest this crate understands.

§

Missing

A required property is not there.

Fields

§kind: String

The node’s kind.

§name: &'static str

What was needed.

§

UnknownWidget

No widget goes by that name.

Fields

§found: String

What the file said.

§

UnknownProperty

The widget has no such property.

Fields

§kind: &'static str

The node’s kind.

§found: String

What the file said.

§accepted: &'static [Property]

Everything that widget does accept.

§

UnknownFormProperty

A property the form node does not carry — often one that belongs to a different kind of form.

Separate from Reason::UnknownProperty because what a form accepts depends on its kind, so the list has to be built rather than pointed at.

Fields

§kind: &'static str

What kind of form it said it was.

§found: String

What the file said.

§accepted: Vec<&'static str>

Everything a form of that kind does accept.

§

WrongType

The property exists; the value was not the shape it takes.

Fields

§kind: &'static str

The node’s kind.

§name: String

The property.

§wanted: &'static str

What it takes, in words.

§

NotAName

A name that should have been one of a fixed set was not.

Fields

§name: String

The property, or the thing being named.

§found: String

What the file said.

§accepted: &'static [&'static str]

Every name that would have worked.

§

UnexpectedChild

A child node that the parent has no use for.

Fields

§parent: String

The parent’s kind.

§found: String

The child’s kind.

§

PlaceholderOutside

A designer’s placeholder content written where the engine would load it.

A table’s rows and a timeline’s events belong in that node’s design { … } block, where every build but a designer’s skips them. Left outside, they would ship to a kiosk — so this is an error rather than a thing quietly ignored, for the same reason an unknown property is.

Fields

§kind: String

The widget’s kind.

§found: String

The child node’s name.

§

PayloadClash

One message name is used with two different payload shapes, so no single enum variant can serve both.

Only codegen raises this. The engine is happy to resolve one name twice, because the application’s match answers each call separately; a generated enum cannot, because Greet is either a variant or a fn(bool) -> M and not both.

Fields

§found: String

The name used twice.

§first: &'static str

What it was first seen as.

§then: &'static str

And then as.

§

NotAnIdentifier

A name in the file cannot be turned into a Rust identifier.

Only codegen. A form loads perfectly well with a node called 2; a struct field cannot be called that.

Fields

§found: String

What the file called it.

§because: &'static str

Why it will not do.

§

Collides

Two names in the file become one Rust identifier.

Only codegen. full-name and full_name are two nodes to a form file and one field to Rust.

Fields

§found: String

The second name to arrive.

§with: String

The one already there.

§spelled: String

What they both became.

§

UnknownMessage

The application’s resolver did not know a message name.

Fields

§found: String

The name in the file.

§

WrongMessage

The resolver knew the name but gave back the wrong shape of message.

Fields

§found: String

The name in the file.

§wanted: &'static str

What the widget needs.

§

Asset

A picture the application’s loader would not load.

Fields

§path: String

The path in the file.

§

DuplicateName

Two nodes claim the same name.

Fields

§name: String

The name.

§

TwoFocuses

More than one node asked for the caret.

§

TreeRefused

The tree refused a node, which it does when its parent is gone.

§

TooDeep

The file nests deeper than this crate will follow.

Fields

§limit: usize

The limit.

§

TooLarge

The file is larger than this crate will read.

Fields

§limit: usize

The limit, in bytes.

§

Unbalanced

A brace has no partner.

Refused by the same byte scan that counts depth, and for the same reason: a file whose braces do not balance cannot parse whatever the parser does with it, and kdl can spend an unbounded amount of time discovering that. Saying it up front costs one pass and gives a better position than the recovery would.

Fields

§open: bool

true for a { that is never closed, false for a } that closes nothing.

§

CommentedTooDeep

The file nests commented-out children blocks past what the parser can be asked to read.

kdl takes time that doubles with every commented-out block nested inside another: a hundred bytes of them is twenty seconds, and three hundred is longer than anyone will wait. So this is refused by a byte scan before the parser is handed the file at all — the same treatment, and for the same reason, as nesting past MAX_DEPTH, which overflows its stack. See MAX_COMMENTED_DEPTH.

Fields

§limit: usize

The limit, in levels.

§

TooSlow

The parse was still running when the caller’s deadline passed, so it was abandoned and the file was not read.

Only Form::parse_within raises this, and only a caller who asked for a deadline can get it. It says nothing about the file beyond how long it was taking: a hostile one that has found a corner of kdl that takes exponential time looks exactly like a legitimate one on a machine that is too slow for the number chosen. The position is the top of the file, because nothing in it has been read.

Fields

§limit: Duration

The time the caller allowed.

§

NoThread

A bounded parse could not be started, so the file was not read at all.

Form::parse_within works on a thread it can walk away from, and this says there was no such thread to be had: either MAX_ABANDONED earlier parses are still running past their deadlines — a wedged thread each, and the point of the limit is that a machine does not fill up with them — or the system refused a thread outright.

Fields

§abandoned: usize

How many earlier parses are still running past their deadline.

§

NotPreserved

The parser could not keep the file byte-for-byte.

Everything this crate does — undo, the designer’s save, a text editor alongside — stands on Form::text reproducing what was opened, and a file that cannot be reproduced would silently lose bytes on the first save. Refusing it is the honest alternative.

The known causes are all one thing — kdl dropping the trivia between a closing brace and the next node, whether that is trailing whitespace or a comment written on the brace’s line — and all of it is put back before this is ever raised. So reaching this means a shape nobody has seen yet, which is what the fuzz target parse_form is hunting for.

§

NoSuchNode

An edit named a node that is not there.

Fields

§path: Vec<usize>

The child path that went nowhere.

§

IntoItself

A move would have put a node inside itself.

Or would have moved the form, which is the document rather than a node in it. Both are the same mistake — a tree cannot contain its own root — and both come from a drag that ended where it should not have been allowed to.

Fields

§path: Vec<usize>

The node the move named.

§

NoArgument

An edit set the positional argument of a node written without one.

An argument comes before every property, and no edit puts something at the front of a line without rewriting the line. Setting the property that argument stands for is what to do instead.

§

WrongKind

An edit would have put a number where a string lives, or the reverse.

Not a matter of reversibility — an edit’s inverse restores the text that was there, so any value can be put back. It is a matter of what the file would become: placeholder=70 parses and then will not build, and an editor holding the widget’s own descriptor already knows better. So the door refuses it rather than the loader, three steps later.

A number replacing a number is not this, whichever way it is written: value=70 becoming value=70.5 is an ordinary edit.

Fields

§name: String

The property.

§holds: &'static str

What it holds now.

§given: &'static str

What the edit offered.

Trait Implementations§

Source§

impl Clone for Reason

Source§

fn clone(&self) -> Reason

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 Debug for Reason

Source§

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

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

impl PartialEq for Reason

Source§

fn eq(&self, other: &Reason) -> 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 Reason

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> AsAny for T
where T: Any,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Borrows as dyn Any.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Mutably borrows as dyn Any.
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.