mf2_syntax/error.rs
1//! Errors of `mf2-syntax`'s fallible operations.
2//!
3//! Syntax and data-model errors are not Rust errors: they are
4//! [`mf2_model::Diagnostic`]s, reported alongside a best-effort result. This
5//! type is for operations that cannot produce a result at all.
6
7/// A data model that MF2 syntax cannot represent (see [`crate::serialize`]).
8#[derive(Clone, Copy, PartialEq, Eq, Debug, thiserror::Error)]
9#[non_exhaustive]
10pub enum Error {
11 /// Text or a literal contains U+0000, which MF2 syntax cannot express
12 /// (the grammar excludes it everywhere and has no escape for it).
13 #[error("text or literal contains U+0000, which MF2 syntax cannot represent")]
14 Nul,
15 /// A variable, function, option, markup or attribute name is not an MF2
16 /// name (or identifier).
17 #[error("{0} is not a valid MF2 name")]
18 InvalidName(NameRole),
19 /// An input declaration's name differs from its variable's name.
20 #[error("an input declaration's name differs from its variable's name")]
21 InputNameMismatch,
22 /// A select message has no selector (`.match` needs one).
23 #[error("a select message needs at least one selector")]
24 NoSelectors,
25 /// A select message has no variant.
26 #[error("a select message needs at least one variant")]
27 NoVariants,
28 /// A variant has no key.
29 #[error("a variant needs at least one key")]
30 NoKeys,
31 /// A message, declaration, key, option value, pattern part or
32 /// expression of a kind this version does not know (the model's enums
33 /// are not exhaustive).
34 #[error("a part of the message of an unknown kind")]
35 UnknownNode,
36}
37
38/// Which kind of name was invalid.
39#[derive(Clone, Copy, PartialEq, Eq, Debug)]
40#[non_exhaustive]
41pub enum NameRole {
42 /// A variable (reference or declaration).
43 Variable,
44 /// A function identifier.
45 Function,
46 /// An option identifier.
47 Option,
48 /// A markup identifier.
49 Markup,
50 /// An attribute identifier.
51 Attribute,
52}
53
54impl core::fmt::Display for NameRole {
55 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
56 f.write_str(match self {
57 NameRole::Variable => "a variable name",
58 NameRole::Function => "a function identifier",
59 NameRole::Option => "an option identifier",
60 NameRole::Markup => "a markup identifier",
61 NameRole::Attribute => "an attribute identifier",
62 })
63 }
64}