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