rename crate to cow-mail

This commit is contained in:
2026-10-10 21:20:33 +02:00
parent 85b2a6bdce
commit 275fd7a0fe
7 changed files with 35 additions and 30 deletions
+6 -1
View File
@@ -1,8 +1,13 @@
[package] [package]
name = "email-message" name = "cow-mail"
version = "0.0.1" version = "0.0.1"
authors = ["Thomas Oettli <spacefreak@noop.ch>"] authors = ["Thomas Oettli <spacefreak@noop.ch>"]
edition = "2024" edition = "2024"
description = "Parse, modify and serialize email messages (RFC 5322/MIME) with copy-on-write, byte-exact round-trip"
repository = "https://github.com/spacefreak86/cow-mail"
license = "GPL-3.0-only"
keywords = ["email", "mime", "rfc5322", "parser", "cow"]
categories = ["email", "parser-implementations"]
[profile.release] [profile.release]
lto = true lto = true
+4 -4
View File
@@ -1,4 +1,4 @@
# email-message # cow-mail
A Rust library for parsing, modifying and serializing email messages (RFC 5322 / MIME). A Rust library for parsing, modifying and serializing email messages (RFC 5322 / MIME).
@@ -14,7 +14,7 @@ messages and for anything that has to pass a message through unchanged.
## Quickstart ## Quickstart
```rust ```rust
use email_message::{CowMail, HeaderMap, Mail}; use cow_mail::{CowMail, HeaderMap, Mail};
let raw = b"Subject: Hello\r\n\ let raw = b"Subject: Hello\r\n\
Content-Type: text/plain\r\n\ Content-Type: text/plain\r\n\
@@ -31,7 +31,7 @@ assert_eq!(mail.get_content().unwrap(), "Hi there");
assert_eq!(mail.serialize().concat(), raw.to_vec()); assert_eq!(mail.serialize().concat(), raw.to_vec());
// Modify it. // Modify it.
mail.add_header("X-Mailer", "email-message"); mail.add_header("X-Mailer", "cow-mail");
mail.set_text_body("Hi again").unwrap(); mail.set_text_body("Hi again").unwrap();
let out: Vec<u8> = mail.serialize().concat(); let out: Vec<u8> = mail.serialize().concat();
@@ -41,7 +41,7 @@ assert!(out.starts_with(b"Subject: Hello"));
Building a multipart message from scratch: Building a multipart message from scratch:
```rust ```rust
use email_message::{CowMail, HeaderMap, Mail, MediaType, names}; use cow_mail::{CowMail, HeaderMap, Mail, MediaType, names};
let mut mail = CowMail::default(); let mut mail = CowMail::default();
mail.add_header("Subject", "Report"); mail.add_header("Subject", "Report");
+1 -1
View File
@@ -94,7 +94,7 @@ impl From<BodyContent> for Vec<u8> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{ContentTransferEncoding, body::encode}; /// use cow_mail::{ContentTransferEncoding, body::encode};
/// ///
/// // Plain ASCII needs no encoding at all. /// // Plain ASCII needs no encoding at all.
/// let (bytes, encoding) = encode("hello"); /// let (bytes, encoding) = encode("hello");
+1 -1
View File
@@ -41,7 +41,7 @@ fn encode(encode_buf: &mut String, writer: &mut EmailWriter) {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::header::encode_header_value; /// use cow_mail::header::encode_header_value;
/// ///
/// // Plain text is left alone. /// // Plain text is left alone.
/// assert_eq!(encode_header_value("Subject", "a test"), "a test"); /// assert_eq!(encode_header_value("Subject", "a test"), "a test");
+9 -9
View File
@@ -42,7 +42,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, HeaderMap}; /// use cow_mail::{CowMail, HeaderMap};
/// let mail = CowMail::try_from(concat!( /// let mail = CowMail::try_from(concat!(
/// "Subject: Test\n", /// "Subject: Test\n",
/// "Subject: Test1\n", /// "Subject: Test1\n",
@@ -80,7 +80,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, HeaderMap}; /// use cow_mail::{CowMail, HeaderMap};
/// let mail = CowMail::try_from(concat!( /// let mail = CowMail::try_from(concat!(
/// "Subject: Test\n", /// "Subject: Test\n",
/// "Subject: Test1", /// "Subject: Test1",
@@ -104,7 +104,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, HeaderMap}; /// use cow_mail::{CowMail, HeaderMap};
/// let mut mail = CowMail::default(); /// let mut mail = CowMail::default();
/// mail.add_header("Subject", "Test"); /// mail.add_header("Subject", "Test");
/// assert_eq!(mail.find_value("Subject").unwrap(), "Test"); /// assert_eq!(mail.find_value("Subject").unwrap(), "Test");
@@ -124,7 +124,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, Header, HeaderMap}; /// use cow_mail::{CowMail, Header, HeaderMap};
/// let mut mail = CowMail::try_from(concat!( /// let mut mail = CowMail::try_from(concat!(
/// "Subject: Test\n", /// "Subject: Test\n",
/// "To: \"John Doe\" <john.doe@example.com>\n", /// "To: \"John Doe\" <john.doe@example.com>\n",
@@ -153,7 +153,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, Header, HeaderMap}; /// use cow_mail::{CowMail, Header, HeaderMap};
/// let mut mail = CowMail::try_from(concat!( /// let mut mail = CowMail::try_from(concat!(
/// "Subject: Test1\n", /// "Subject: Test1\n",
/// "To: \"John Doe\" <john.doe@example.com>\n", /// "To: \"John Doe\" <john.doe@example.com>\n",
@@ -192,7 +192,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, Header, HeaderMap}; /// use cow_mail::{CowMail, Header, HeaderMap};
/// let mut mail = CowMail::try_from(concat!( /// let mut mail = CowMail::try_from(concat!(
/// "Subject: Test\n", /// "Subject: Test\n",
/// "To: \"John Doe\" <john.doe@example.com>\n", /// "To: \"John Doe\" <john.doe@example.com>\n",
@@ -221,7 +221,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, Header, HeaderMap}; /// use cow_mail::{CowMail, Header, HeaderMap};
/// let mut mail = CowMail::try_from(concat!( /// let mut mail = CowMail::try_from(concat!(
/// "Subject: Test1\n", /// "Subject: Test1\n",
/// "To: \"John Doe\" <john.doe@example.com>\n", /// "To: \"John Doe\" <john.doe@example.com>\n",
@@ -251,7 +251,7 @@ pub trait HeaderMap<'a, H: Header<'a> + 'a> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use email_message::{CowMail, Header, HeaderMap}; /// use cow_mail::{CowMail, Header, HeaderMap};
/// let mut mail = CowMail::try_from(concat!( /// let mut mail = CowMail::try_from(concat!(
/// "Subject: Test1\n", /// "Subject: Test1\n",
/// "To: \"John Doe\" <john.doe@example.com>\n", /// "To: \"John Doe\" <john.doe@example.com>\n",
@@ -315,7 +315,7 @@ pub(crate) fn build_headers<'a, H: Header<'a>>(
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowHeader, HeaderMap, parse_headers}; /// use cow_mail::{CowHeader, HeaderMap, parse_headers};
/// ///
/// let raw = b"Subject: Hi\r\nTo: nobody\r\n\r\nbody\r\n"; /// let raw = b"Subject: Hi\r\nTo: nobody\r\n\r\nbody\r\n";
/// let (headers, body_idx) = parse_headers::<CowHeader>(&raw[..]).unwrap(); /// let (headers, body_idx) = parse_headers::<CowHeader>(&raw[..]).unwrap();
+3 -3
View File
@@ -173,7 +173,7 @@ pub trait Header<'a>: Clone + Display {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowHeader, Header}; /// use cow_mail::{CowHeader, Header};
/// ///
/// let header = CowHeader::new("Content-Type", "text/plain; charset=utf-8"); /// let header = CowHeader::new("Content-Type", "text/plain; charset=utf-8");
/// assert_eq!(header.get_param("charset").unwrap(), "utf-8"); /// assert_eq!(header.get_param("charset").unwrap(), "utf-8");
@@ -262,7 +262,7 @@ impl<'a, T: Header<'a>> From<&'_ T> for RFC2045HeaderValue<String> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowHeader, Header}; /// use cow_mail::{CowHeader, Header};
/// ///
/// let header = CowHeader::new("Subject", "Grüße"); /// let header = CowHeader::new("Subject", "Grüße");
/// ///
@@ -430,7 +430,7 @@ fn build_header<'a, H: Header<'a>>(
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowHeader, Header, parse_header}; /// use cow_mail::{CowHeader, Header, parse_header};
/// ///
/// let raw = b"Subject: Hi\r\nTo: nobody\r\n"; /// let raw = b"Subject: Hi\r\nTo: nobody\r\n";
/// let (header, next) = parse_header::<CowHeader>(&raw[..]).unwrap(); /// let (header, next) = parse_header::<CowHeader>(&raw[..]).unwrap();
+11 -11
View File
@@ -311,7 +311,7 @@ pub trait Mail<'a, T: Header<'a> + 'a>: HeaderMap<'a, T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowMail, Mail}; /// use cow_mail::{CowMail, Mail};
/// ///
/// let raw = b"Content-Type: text/plain\r\n\ /// let raw = b"Content-Type: text/plain\r\n\
/// Content-Transfer-Encoding: base64\r\n\ /// Content-Transfer-Encoding: base64\r\n\
@@ -448,7 +448,7 @@ enum BodyCheckStatus {
/// All three are empty for a part that was built rather than parsed. /// All three are empty for a part that was built rather than parsed.
/// ///
/// ``` /// ```
/// use email_message::{CowMail, HeaderMap, Mail}; /// use cow_mail::{CowMail, HeaderMap, Mail};
/// ///
/// let raw = b"Subject: Hi\r\n\r\nbody\r\n"; /// let raw = b"Subject: Hi\r\n\r\nbody\r\n";
/// let mut mail = CowMail::try_from(&raw[..]).unwrap(); /// let mut mail = CowMail::try_from(&raw[..]).unwrap();
@@ -466,7 +466,7 @@ enum BodyCheckStatus {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowMail, Header, HeaderMap, Mail}; /// use cow_mail::{CowMail, Header, HeaderMap, Mail};
/// ///
/// let raw = b"Subject: Hi\r\n\r\nbody\r\n"; /// let raw = b"Subject: Hi\r\n\r\nbody\r\n";
/// let mut mail = CowMail::try_from(&raw[..]).unwrap(); /// let mut mail = CowMail::try_from(&raw[..]).unwrap();
@@ -590,7 +590,7 @@ impl<'a, H: Header<'a> + 'a> CowMail<'a, H> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowMail, HeaderMap, Mail, MediaType, names}; /// use cow_mail::{CowMail, HeaderMap, Mail, MediaType, names};
/// ///
/// let mut part = CowMail::default(); /// let mut part = CowMail::default();
/// part.set_content("<p>hi</p>", Some(MediaType::new(names::TEXT, names::HTML))); /// part.set_content("<p>hi</p>", Some(MediaType::new(names::TEXT, names::HTML)));
@@ -758,7 +758,7 @@ impl<'a, H: Header<'a> + 'a> CowMail<'a, H> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{BodyType, CowMail, Mail}; /// use cow_mail::{BodyType, CowMail, Mail};
/// ///
/// let raw = b"Content-Type: multipart/alternative; boundary=\"b\"\r\n\ /// let raw = b"Content-Type: multipart/alternative; boundary=\"b\"\r\n\
/// \r\n\ /// \r\n\
@@ -853,7 +853,7 @@ impl<'a, H: Header<'a> + 'a> CowMail<'a, H> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowMail, HeaderMap, Mail}; /// use cow_mail::{CowMail, HeaderMap, Mail};
/// ///
/// let mut mail = CowMail::default(); /// let mut mail = CowMail::default();
/// mail.add_header("Subject", "Hi"); /// mail.add_header("Subject", "Hi");
@@ -917,7 +917,7 @@ impl<'a, H: Header<'a> + 'a> CowMail<'a, H> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowMail, HeaderMap, Mail, MediaType, names}; /// use cow_mail::{CowMail, HeaderMap, Mail, MediaType, names};
/// ///
/// let mut mail = CowMail::default(); /// let mut mail = CowMail::default();
/// mail.set_text_body("see attached").unwrap(); /// mail.set_text_body("see attached").unwrap();
@@ -1087,7 +1087,7 @@ impl<'a, H: Header<'a> + 'a> CowMail<'a, H> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{BodyType, CowMail, HeaderMap, Mail}; /// use cow_mail::{BodyType, CowMail, HeaderMap, Mail};
/// ///
/// let mut mail = CowMail::default(); /// let mut mail = CowMail::default();
/// mail.add_header("Subject", "Hi"); /// mail.add_header("Subject", "Hi");
@@ -1169,7 +1169,7 @@ impl<'a, H: Header<'a> + 'a> CowMail<'a, H> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::CowMail; /// use cow_mail::CowMail;
/// ///
/// let raw = b"Subject: Hi\r\n\r\nbody\r\n"; /// let raw = b"Subject: Hi\r\n\r\nbody\r\n";
/// let mail = CowMail::try_from(&raw[..]).unwrap(); /// let mail = CowMail::try_from(&raw[..]).unwrap();
@@ -1242,7 +1242,7 @@ impl<'a> TryFrom<&'a [u8]> for CowMail<'a, CowHeader<'a>> {
/// ///
/// ``` /// ```
/// use std::io::Read; /// use std::io::Read;
/// use email_message::{CowMail, CowMailReader}; /// use cow_mail::{CowMail, CowMailReader};
/// ///
/// let raw = b"Subject: Hi\r\n\r\nbody\r\n"; /// let raw = b"Subject: Hi\r\n\r\nbody\r\n";
/// let mail = CowMail::try_from(&raw[..]).unwrap(); /// let mail = CowMail::try_from(&raw[..]).unwrap();
@@ -1343,7 +1343,7 @@ impl std::io::Read for CowMailReader<'_> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use email_message::{CowHeader, CowMail, HeaderMap, parse_mail}; /// use cow_mail::{CowHeader, CowMail, HeaderMap, parse_mail};
/// ///
/// let raw = b"Subject: Hi\r\n\r\nbody\r\n"; /// let raw = b"Subject: Hi\r\n\r\nbody\r\n";
/// let mail: CowMail<CowHeader> = parse_mail(&raw[..]).unwrap(); /// let mail: CowMail<CowHeader> = parse_mail(&raw[..]).unwrap();