mail_builder/headers/
content_type.rs1use std::borrow::Cow;
2
3use super::{
4 Header,
5 fold::{FoldWriter, write_control_free},
6 rfc2047::write_parameter,
7};
8use crate::writer::Writer;
9
10#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
12pub struct ContentType<'x> {
13 pub c_type: Cow<'x, str>,
14 pub attributes: Vec<(Cow<'x, str>, Cow<'x, str>)>,
15}
16
17impl<'x> ContentType<'x> {
18 pub fn new(c_type: impl Into<Cow<'x, str>>) -> Self {
20 Self {
21 c_type: c_type.into(),
22 attributes: Vec::new(),
23 }
24 }
25
26 pub fn attribute(mut self, key: impl Into<Cow<'x, str>>, value: impl Into<Cow<'x, str>>) -> Self {
28 self.attributes.push((key.into(), value.into()));
29 self
30 }
31
32 pub fn is_text(&self) -> bool {
34 self.c_type
35 .get(..5)
36 .is_some_and(|prefix| prefix.eq_ignore_ascii_case("text/"))
37 }
38
39 pub fn is_attachment(&self) -> bool {
41 self.c_type.eq_ignore_ascii_case("attachment")
42 }
43}
44
45impl Header for ContentType<'_> {
46 fn write_header(&self, output: &mut impl Writer, column: usize) {
47 let mut folder = FoldWriter::new(output, column);
48 write_control_free(&mut folder, self.c_type.as_bytes());
49
50 if let Some((last, head)) = self.attributes.split_last() {
51 for (key, value) in head {
52 folder.semicolon();
53 write_parameter(&mut folder, key, value, 1);
54 }
55 folder.semicolon();
56 write_parameter(&mut folder, &last.0, &last.1, 0);
57 }
58
59 folder.finish();
60 }
61}