### Rust Email Parsing Example Source: https://github.com/stalwartlabs/mail-parser/blob/main/README.md Demonstrates parsing a raw email byte string into a structured `Message` object. It covers extracting sender, recipients (including groups), date, subject, and body content (HTML and plain text). It also shows how to access nested messages and attachments, including handling various character encodings and RFC2231 compliant attachment names. ```rust let input = br#"From: Art Vandelay (Vandelay Industries) To: \"Colleagues\": \"James Smythe\" ; Friends: jane@example.com, =?UTF-8?Q?John_Sm=C3=AEth?= ; Date: Sat, 20 Nov 2021 14:22:01 -0800 Subject: Why not both importing AND exporting? =?utf-8?b?4pi6?= Content-Type: multipart/mixed; boundary=\"festivus\"; --festivus Content-Type: text/html; charset=\"us-ascii\" Content-Transfer-Encoding: base64 PGh0bWw+PHA+SSB3YXMgdGhpbmtpbmcgYWJvdXQgcXVpdHRpbmcgZXhwb3J0aW5nJm1k cTsmcmRxdW87IHRvIGZvY3VzIGp1c3Qgb24gdGhlICZsZHF1bztpbXBvcnRpbmcmcmRxdW87LDwvcD48cD5idXRoZW4gSSB0aG91Z2h0LCB3aHkgbm90IGRvIGJvdGg/ICYj4jYzQTA7PC9wPjwvaHRtbD4= --festivus Content-Type: message/rfc822 From: \"Cosmo Kramer\" Subject: Exporting my book about coffee tables Content-Type: multipart/mixed; boundary=\"giddyup\"; --giddyup Content-Type: text/plain; charset=\"utf-16\" Content-Transfer-Encoding: quoted-printable =FF=FE=0C!5=D8"=DD5=D8)=DD5=D8-=DD =005=D8*=DD5=D8"=DD =005=D8"= =DD5=D85=DD5=D8-=DD5=D8,=DD5=D8/=DD5=D81=DD =005=D8*=DD5=D86=DD = =005=D8=1F=DD5=D8,=DD5=D8,=DD5=D8(=DD =005=D8-=DD5=D8)=DD5=D8"= =DD5=D8=1E=DD5=D80=DD5=D8"=DD!=00 --giddyup Content-Type: image/gif; name*1=\"about \"; name*0=\"Book \"; name*2*=utf-8''%e2%98%95 tables.gif Content-Transfer-Encoding: Base64 Content-Disposition: attachment R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 --giddyup-- --festivus-- "#; let message = MessageParser::default().parse(input).unwrap(); // Parses addresses (including comments), lists and groups assert_eq!( message.from().unwrap().first().unwrap(), &Addr::new( "Art Vandelay (Vandelay Industries)".into(), "art@vandelay.com" ) ); assert_eq!( message.to().unwrap().as_group().unwrap(), &[ Group::new( "Colleagues", vec![Addr::new("James Smythe".into(), "james@vandelay.com")] ), Group::new( "Friends", vec![ Addr::new(None, "jane@example.com"), Addr::new("John Smîth".into(), "john@example.com"), ] ) ] ); assert_eq!( message.date().unwrap().to_rfc3339(), "2021-11-20T14:22:01-08:00" ); // RFC2047 support for encoded text in message readers assert_eq!( message.subject().unwrap(), "Why not both importing AND exporting? ☺" ); // HTML and text body parts are returned conforming to RFC8621, Section 4.1.4 assert_eq!( message.body_html(0).unwrap(), concat!( "

I was thinking about quitting the “exporting” to ", "focus just on the “importing”,

but then I thought,", " why not do both? ☺

" ) ); // HTML parts are converted to plain text (and viceversa) when missing assert_eq!( message.body_text(0).unwrap(), concat!( "I was thinking about quitting the “exporting” to focus just on the", " “importing”, ", "but then I thought, why not do both? ☺ " ) ); // Supports nested messages as well as multipart/digest let nested_message = message .attachment(0) // Assuming the first attachment is the nested message .unwrap() .message() .unwrap(); assert_eq!( nested_message.subject().unwrap(), "Exporting my book about coffee tables" ); // Handles UTF-* as well as many legacy encodings assert_eq!( nested_message.body_text(0).unwrap(), "ℌ𝔢𝔩𝔭 𝔪𝔢 𝔢𝔵𝔭𝔬𝔯𝔱 𝔪y 𝔟𝔬𝔬𝔨 𝔭𝔩𝔢𝔞𝔰𝔢!" ); assert_eq!( nested_message.body_html(0).unwrap(), "ℌ𝔢𝔩𝔭 𝔪me 𝔢𝔵𝔭𝔬𝔯𝔱 𝔪y 𝔟𝔬𝔬𝔨 𝔭𝔩𝔢𝔞𝔰𝔢!" ); let nested_attachment = nested_message.attachment(0).unwrap(); assert_eq!(nested_attachment.len(), 42); // Full RFC2231 support for continuations and character sets assert_eq!( nested_attachment.attachment_name().unwrap(), "Book about ☕ tables.gif" ); // Integrates with Serde println!("{}", serde_json::to_string_pretty(&message).unwrap()); ``` -------------------------------- ### Applying the Apache License Source: https://github.com/stalwartlabs/mail-parser/blob/main/LICENSES/Apache-2.0.txt Provides instructions on how to apply the Apache License to a project by including a boilerplate notice with specific fields. ```APIDOC APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" ``` -------------------------------- ### License and Copyright Source: https://github.com/stalwartlabs/mail-parser/blob/main/README.md Details the licensing options (Apache 2.0 or MIT) and copyright information for the mail-parser project. ```text License: Licensed under either of: * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. Copyright: Copyright (C) 2020, Stalwart Labs LLC ``` -------------------------------- ### Rust Cargo Test Commands Source: https://github.com/stalwartlabs/mail-parser/blob/main/README.md Provides commands to run the test suite for the mail-parser library, including options for using MIRI for memory safety checks and fuzzing with cargo-fuzz. ```bash cargo test --all-features ``` ```bash cargo +nightly miri test --all-features ``` ```bash cargo +nightly fuzz run mail_parser ``` ```bash cargo +nightly bench --all-features ``` -------------------------------- ### Apache License Terms and Conditions Source: https://github.com/stalwartlabs/mail-parser/blob/main/LICENSES/Apache-2.0.txt Details the terms and conditions for using, distributing, and modifying the work under the Apache License. It covers recipient obligations, modification notices, retention of notices, and handling of NOTICE files. ```APIDOC License Terms and Conditions: 5. Submission of Contributions: - Contributions submitted to the Licensor are under the terms of this License, without additional conditions. - Separate license agreements may supersede this. 6. Trademarks: - This License does not grant permission to use trade names, trademarks, service marks, or product names of the Licensor. - Exceptions are for reasonable use in describing the origin of the Work and reproducing NOTICE file content. 7. Disclaimer of Warranty: - The Work is provided "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - This includes warranties of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. - User is solely responsible for determining appropriateness and assumes risks. 8. Limitation of Liability: - No Contributor is liable for damages (direct, indirect, special, incidental, consequential) arising from the License or use/inability to use the Work. - This applies regardless of legal theory (tort, contract, etc.), even if advised of the possibility of damages. 9. Accepting Warranty or Additional Liability: - Users may offer support, warranty, indemnity, or liability obligations consistent with this License. - When accepting, users act solely on their own behalf and responsibility. - Users must indemnify, defend, and hold harmless contributors for liabilities incurred due to accepting such terms. ``` -------------------------------- ### Supported RFCs Source: https://github.com/stalwartlabs/mail-parser/blob/main/README.md Lists the RFCs that the mail-parser project conforms to, covering internet message formats, MIME, and related standards. ```text - RFC 822 - Standard for ARPA Internet Text Messages - RFC 5322 - Internet Message Format - RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies - RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types - RFC 2047 - MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text - RFC 2048 - Multipurpose Internet Mail Extensions (MIME) Part Four: Registration Procedures - RFC 2049 - Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples - RFC 2231 - MIME Parameter Value and Encoded Word Extensions: Character Sets, Languages, and Continuations - RFC 2557 - MIME Encapsulation of Aggregate Documents, such as HTML (MHTML) - RFC 2183 - Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field - RFC 2392 - Content-ID and Message-ID Uniform Resource Locators - RFC 3282 - Content Language Headers - RFC 6532 - Internationalized Email Headers - RFC 2152 - UTF-7 - A Mail-Safe Transformation Format of Unicode - RFC 2369 - The Use of URLs as Meta-Syntax for Core Mail List Commands and their Transport through Message Header Fields - RFC 2919 - List-Id: A Structured Field and Namespace for the Identification of Mailing Lists - RFC 3339 - Date and Time on the Internet: Timestamps - RFC 8621 - The JSON Meta Application Protocol (JMAP) for Mail (Section 4.1.4) - RFC 5957 - Internet Message Access Protocol - SORT and THREAD Extensions (Section 2.1) ``` -------------------------------- ### Supported Character Sets Source: https://github.com/stalwartlabs/mail-parser/blob/main/README.md Lists the character sets directly supported by the mail-parser and those supported via the optional 'encoding_rs' dependency. ```text Directly Supported: - UTF-8 - UTF-16, UTF-16BE, UTF-16LE - UTF-7 - US-ASCII - ISO-8859-1 to ISO-8859-16 - CP1250 to CP1258 - KOI8-R, KOI8_U - MACINTOSH - IBM850 - TIS-620 Supported via encoding_rs: - SHIFT_JIS - BIG5 - EUC-JP - EUC-KR - GB18030 - GBK - ISO-2022-JP - WINDOWS-874 - IBM-866 ``` -------------------------------- ### Rust Email Parsing with mail-parser Source: https://github.com/stalwartlabs/mail-parser/blob/main/README.md Demonstrates the core functionality of the mail-parser library for parsing email messages. It highlights the library's adherence to RFC standards and its ability to handle various character sets and MIME parts. ```rust use mail_parser::Message; fn parse_email(raw_email: &str) -> Result { Message::parse(raw_email.as_bytes()) } fn main() { let email_content = "Subject: Test\n\nThis is a test email."; match parse_email(email_content) { Ok(message) => { println!("Subject: {:?}", message.subject()); println!("Text Body: {:?}", message.text_body()); } Err(e) => { eprintln!("Error parsing email: {}", e); } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.