1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! RFC 5322 email message parser.
//!
//! Parses raw email message bytes into a structured [`ParsedEmail`] representation.
//! Handles partial messages (headers + truncated body) gracefully, extracting
//! whatever content is available.
//!
//! The parser is split into two layers:
//! - **Wire parser** ([`wire`]) — purely syntactic, splits bytes into structure
//! (headers, body) without semantic interpretation.
//! - **Interpreter** ([`interpret`]) — converts wire-parsed data into the
//! public [`ParsedEmail`] type by performing RFC 2047 decoding, address
//! parsing, date parsing, MIME tree walking, and charset conversion.
//!
//! # References
//! - RFC 5322 Sections 2–3 (message syntax, header/body separation, field definitions)
//! - RFC 2045 Sections 5–6 (Content-Type, Content-Transfer-Encoding)
//! - RFC 2046 Sections 4–5 (discrete/composite media types, multipart boundaries)
//! - RFC 2047 Sections 2–4 (encoded-word syntax and decoding)
//! - RFC 2183 Section 2 (Content-Disposition field)
//! - RFC 2231 Sections 3–4 (MIME parameter continuations, charset/language)
//! - RFC 6532 Section 3 (internationalized UTF-8 headers)
use crateError;
use crateParsedEmail;
// Re-export pub(crate) helpers used by other modules in the crate.
// `decode_encoded_words` is used by `crate::fuzz` behind `#[cfg(fuzzing)]`,
// which is not active during normal compilation — suppress the warning.
pub use decode_encoded_words;
pub use find_paren_outside_quotes;
pub use normalize_display_name_phrase;
pub use parse_address_list;
pub use parse_rfc5322_date;
pub use strip_comments;
/// Parses raw email message bytes into a structured representation.
///
/// Handles partial messages (headers + truncated body) gracefully,
/// extracting whatever content is available. Returns [`Error::EmptyInput`]
/// for empty input. Malformed but still usable messages that omit the
/// required `From` header are accepted with an empty `from` list.
///
/// # References
/// - RFC 5322 Sections 2.1–2.3 (header/body separation, line length)
/// - RFC 5322 Sections 3.3–3.6 (date-time, address, field definitions)
/// - RFC 2045 Section 6 (Content-Transfer-Encoding decoding)
/// - RFC 2046 Sections 5.1–5.2 (multipart boundary parsing)
/// - RFC 2047 Sections 3–4 (encoded-word decoding in headers)
/// - RFC 2183 Section 2 (Content-Disposition parsing)
/// - RFC 2231 Sections 3–4 (parameter continuations, charset/language)
/// - RFC 6532 Section 3 (internationalized header fields)
/// Parses only the headers of a raw email message, skipping body/MIME processing.
///
/// This is faster than [`parse_email`] when only metadata is needed (e.g.,
/// building a message list). Body-related fields (`body_text`, `body_html`,
/// `attachments`) are always empty/`None`.
///
/// # References
/// - RFC 5322 Sections 2.1–2.2 (header/body separation, header folding)
/// - RFC 5322 Sections 3.3–3.6 (date-time, address, field definitions)
/// - RFC 2047 Sections 3–4 (encoded-word decoding in headers)
/// - RFC 6532 Section 3 (internationalized header fields)
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
// Tests are placed in mod.rs because they exercise the full parse pipeline
// (wire → interpret) through the public `parse_email`/`parse_headers_only`
// entry points, plus direct calls to internal functions from both layers.
// Using `use` imports below makes all needed functions available to `super::*`
// in the test module.