Skip to main content

mime_tree/
lib.rs

1//! RFC 5322 / MIME parser producing a byte-range-indexed part tree.
2//!
3//! # Quick start
4//!
5//! ```rust
6//! use mime_tree::{parse, decode_body_value};
7//!
8//! let raw = b"From: alice@example.com\r\n\
9//!             Content-Type: text/plain; charset=utf-8\r\n\
10//!             \r\n\
11//!             Hello, world!\r\n";
12//!
13//! let msg = parse(raw).expect("parse failed");
14//!
15//! // text_body / html_body / attachments follow RFC 8621 §4.1.4.
16//! assert_eq!(msg.text_body, vec!["1"]);
17//! assert_eq!(msg.html_body, vec!["1"]); // mirrors text_body for non-multipart
18//!
19//! // Decode a body part on demand (transfer-decode + charset-convert).
20//! let part = msg.part_index.find_by_id("1").unwrap();
21//! let decoded = decode_body_value(raw, part, None).unwrap();
22//! assert_eq!(decoded.value, "Hello, world!\r\n");
23//! ```
24//!
25//! # Design
26//!
27//! - `parse()` returns a [`ParsedMessage`] with the MIME part tree and RFC 8621
28//!   `text_body` / `html_body` / `attachments` part-ID lists.
29//! - Each [`ParsedPart`] carries `(offset, length)` byte ranges into the
30//!   original `&[u8]` — no raw bytes are stored internally.
31//! - `decode_body_value()` decodes a part's body on demand: transfer-encoding
32//!   decode (Base64, QP, identity) followed by charset conversion via `encoding_rs`.
33//! - Parsing is best-effort: malformed input yields a partial result plus
34//!   `ParsedMessage::warnings`. Only empty input or no-headers returns `Err`.
35//! - No JMAP dependency. No async. No `unsafe`.
36
37mod decode;
38mod error;
39mod header_typed;
40mod message;
41mod parse;
42mod part;
43mod uuencode;
44mod walk;
45mod yenc;
46
47pub use error::ParseError;
48pub use header_typed::{
49    parse_addresses, parse_date, parse_grouped_addresses, parse_header_typed,
50    parse_header_typed_from, parse_message_ids, parse_raw, parse_text, parse_urls, AddressGroup,
51    EmailAddress, HeaderDateTime, HeaderForm, HeaderValueTyped, TzSign, UnknownHeaderForm,
52};
53pub use message::{DecodedBodyValue, ParsedMessage};
54pub use parse::{decode_body_value, parse};
55pub use part::{ParsedHeader, ParsedPart, TransferEncoding};
56pub use uuencode::{scan_inline_uuencode, InlineUUBlock};
57pub use yenc::{scan_inline_yencode, InlineYEncBlock};