Skip to main content

mf2_runtime/
error.rs

1//! Formatting errors: small plain values (`plans/03-runtime.md` §2.2). They
2//! derive `thiserror::Error` for server and test use; its `Display` is never
3//! reached from the client path (B12).
4
5use mf2_model::ErrorKind;
6
7/// An error reported while formatting. Formatting still produces output.
8#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, thiserror::Error)]
9#[repr(u8)]
10#[non_exhaustive]
11pub enum FormatError {
12    /// Unresolved Variable: no value for a variable.
13    #[error("unresolved variable")]
14    UnresolvedVariable,
15    /// Unknown Function: the registry has no handler for a function.
16    #[error("unknown function")]
17    UnknownFunction,
18    /// Bad Selector: a selector's value does not support selection.
19    #[error("bad selector")]
20    BadSelector,
21    /// Bad Operand: a function cannot take its operand.
22    #[error("bad operand")]
23    BadOperand,
24    /// Bad Option: an option or its value is not valid for the function.
25    #[error("bad option")]
26    BadOption,
27    /// Bad Variant Key: a key a selector cannot compare against.
28    #[error("bad variant key")]
29    BadVariantKey,
30    /// Unsupported Operation: valid, but not supported by this handler or
31    /// configuration (or past an implementation limit).
32    #[error("unsupported operation")]
33    UnsupportedOperation,
34    /// Any other failure of a function handler.
35    #[error("message function error")]
36    MessageFunctionError,
37    /// No variant matched — only a catalog built from an invalid model (no
38    /// fallback variant, or key counts unlike the selector count) has one.
39    /// The message formats as `{�}`.
40    #[error("no variant matched (missing fallback variant)")]
41    MissingFallbackVariant,
42    /// The id is not in this catalog. Nothing is written.
43    #[error("missing message")]
44    MissingMessage,
45    /// The message's catalog record is malformed: `{�}` in its place, and
46    /// the message ends there.
47    #[error("malformed catalog record")]
48    Malformed,
49}
50
51impl FormatError {
52    /// The MF2 error kind (`mf2_model::ErrorKind`); `None` for
53    /// [`FormatError::MissingMessage`] and [`FormatError::Malformed`], which
54    /// are about the catalog, not the message.
55    pub const fn kind(self) -> Option<ErrorKind> {
56        Some(match self {
57            FormatError::UnresolvedVariable => ErrorKind::UnresolvedVariable,
58            FormatError::UnknownFunction => ErrorKind::UnknownFunction,
59            FormatError::BadSelector => ErrorKind::BadSelector,
60            FormatError::BadOperand => ErrorKind::BadOperand,
61            FormatError::BadOption => ErrorKind::BadOption,
62            FormatError::BadVariantKey => ErrorKind::BadVariantKey,
63            FormatError::UnsupportedOperation => ErrorKind::UnsupportedOperation,
64            FormatError::MessageFunctionError => ErrorKind::MessageFunctionError,
65            FormatError::MissingFallbackVariant => ErrorKind::MissingFallbackVariant,
66            FormatError::MissingMessage | FormatError::Malformed => return None,
67        })
68    }
69}