mail_builder/headers/
message_id.rs1use std::borrow::Cow;
8
9use crate::mime::make_boundary;
10
11use super::Header;
12
13#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
15pub struct MessageId<'x> {
16 pub id: Vec<Cow<'x, str>>,
17}
18
19impl<'x> MessageId<'x> {
20 pub fn new(id: impl Into<Cow<'x, str>>) -> Self {
22 Self {
23 id: vec![id.into()],
24 }
25 }
26
27 pub fn new_list<T, U>(ids: T) -> Self
29 where
30 T: Iterator<Item = U>,
31 U: Into<Cow<'x, str>>,
32 {
33 Self {
34 id: ids.map(|s| s.into()).collect(),
35 }
36 }
37}
38
39impl<'x> From<&'x str> for MessageId<'x> {
40 fn from(value: &'x str) -> Self {
41 Self::new(value)
42 }
43}
44
45impl From<String> for MessageId<'_> {
46 fn from(value: String) -> Self {
47 Self::new(value)
48 }
49}
50
51impl<'x> From<&[&'x str]> for MessageId<'x> {
52 fn from(value: &[&'x str]) -> Self {
53 MessageId {
54 id: value.iter().map(|&s| s.into()).collect(),
55 }
56 }
57}
58
59impl<'x> From<&'x [String]> for MessageId<'x> {
60 fn from(value: &'x [String]) -> Self {
61 MessageId {
62 id: value.iter().map(|s| s.into()).collect(),
63 }
64 }
65}
66
67impl<'x, T> From<Vec<T>> for MessageId<'x>
68where
69 T: Into<Cow<'x, str>>,
70{
71 fn from(value: Vec<T>) -> Self {
72 MessageId {
73 id: value.into_iter().map(|s| s.into()).collect(),
74 }
75 }
76}
77
78pub fn generate_message_id_header(
79 mut output: impl std::io::Write,
80 hostname: &str,
81) -> std::io::Result<()> {
82 output.write_all(b"<")?;
83 output.write_all(make_boundary(".").as_bytes())?;
84 output.write_all(b"@")?;
85 output.write_all(hostname.as_bytes())?;
86 output.write_all(b">")
87}
88
89impl Header for MessageId<'_> {
90 fn write_header(
91 &self,
92 mut output: impl std::io::Write,
93 mut bytes_written: usize,
94 ) -> std::io::Result<usize> {
95 for (pos, id) in self.id.iter().enumerate() {
96 if pos > 0 {
97 if bytes_written + id.len() + 2 >= 76 {
98 output.write_all(b"\r\n\t")?;
99 bytes_written = 1;
100 } else {
101 output.write_all(b" ")?;
102 bytes_written += 1;
103 }
104 }
105
106 output.write_all(b"<")?;
107 output.write_all(id.as_bytes())?;
108 output.write_all(b">")?;
109 bytes_written += id.len() + 2;
110 }
111
112 if bytes_written > 0 {
113 output.write_all(b"\r\n")?;
114 }
115
116 Ok(0)
117 }
118}