Skip to main content

daaki_message/
error.rs

1//! Typed error enum for email message parsing and building.
2//!
3//! # References
4//! - RFC 5322 (Internet Message Format)
5//! - RFC 2045–2047 (MIME)
6
7/// Errors that can occur during email message parsing or building.
8#[non_exhaustive]
9#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum Error {
12    /// Empty input provided to the parser (RFC 5322 Section 3.5 — a valid
13    /// message must contain at least header fields, so zero bytes is invalid).
14    #[error("empty input: no message bytes provided")]
15    EmptyInput,
16
17    /// Missing required `From` header (RFC 5322 Section 3.6.2).
18    #[error("missing required From header (RFC 5322 Section 3.6.2)")]
19    MissingFrom,
20
21    /// Date header could not be parsed per RFC 5322 Section 3.3.
22    #[error("invalid date: {0}")]
23    InvalidDate(String),
24
25    /// Syntactically invalid email address (RFC 5322 Section 3.4).
26    #[error("invalid email address: {0}")]
27    InvalidAddress(String),
28
29    /// Missing `Sender` header when `From` has multiple addresses
30    /// (RFC 5322 Section 3.6.2).
31    ///
32    /// RFC 5322: "If the from field contains more than one mailbox
33    /// specification in the mailbox-list, then the sender field, containing
34    /// the field value corresponding to the responsible agent of the message
35    /// MUST be present in the message."
36    #[error(
37        "Sender header required when From has multiple addresses \
38         (RFC 5322 Section 3.6.2)"
39    )]
40    MissingSender,
41
42    /// Invalid header field name (RFC 5322 Section 2.2).
43    ///
44    /// The name is empty, contains non-ftext characters, or is otherwise
45    /// malformed per RFC 5322 Section 2.2 (`field-name = 1*ftext`).
46    #[error("invalid header name: {0}")]
47    InvalidHeaderName(String),
48
49    /// Invalid message-ID (RFC 5322 Section 3.6.4).
50    ///
51    /// The value is empty, missing the `@` separator, contains prohibited
52    /// characters, or has empty `id-left` / `id-right` parts.
53    #[error("invalid message-ID: {0}")]
54    InvalidMessageId(String),
55
56    /// A header value contains a token or whitespace run that cannot be folded
57    /// within the 998-octet line limit (RFC 5322 Sections 2.1.1, 2.2.3).
58    #[error("header line too long: {0}")]
59    HeaderLineTooLong(String),
60
61    /// An `extra_headers` entry uses a field name reserved for standard headers
62    /// managed by the builder (RFC 5322 Section 3.6).
63    #[error("reserved header name: {0}")]
64    ReservedHeaderName(String),
65
66    /// An attachment violates MIME constraints — invalid content encoding,
67    /// missing required headers, or prohibited bytes (RFC 2045/2046).
68    #[error("invalid attachment: {0}")]
69    InvalidAttachment(String),
70
71    /// A trace header (Return-Path / Received) violates
72    /// RFC 5322 Section 3.6.7 syntax or cardinality rules.
73    #[error("invalid trace header: {0}")]
74    InvalidTraceHeader(String),
75
76    /// A Resent-* header violates RFC 5322 Section 3.6.6 syntax,
77    /// cardinality, or block-grouping rules.
78    #[error("invalid resent header: {0}")]
79    InvalidResentHeader(String),
80}
81
82#[cfg(test)]
83#[path = "error_tests.rs"]
84mod tests;