Skip to main content

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}