lettre/message/header/
content.rs

1use std::{
2    fmt::{Display, Formatter as FmtFormatter, Result as FmtResult},
3    str::FromStr,
4};
5
6use super::{Header, HeaderName, HeaderValue};
7use crate::BoxError;
8
9/// `Content-Transfer-Encoding` of the body
10///
11/// The `Message` builder takes care of choosing the most
12/// efficient encoding based on the chosen body, so in most
13/// use-caches this header shouldn't be set manually.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16#[derive(Default)]
17pub enum ContentTransferEncoding {
18    /// ASCII
19    SevenBit,
20    /// Quoted-Printable encoding
21    QuotedPrintable,
22    /// base64 encoding
23    #[default]
24    Base64,
25    /// Requires `8BITMIME`
26    EightBit,
27    /// Binary data
28    Binary,
29}
30
31impl Header for ContentTransferEncoding {
32    fn name() -> HeaderName {
33        HeaderName::new_from_ascii_str("Content-Transfer-Encoding")
34    }
35
36    fn parse(s: &str) -> Result<Self, BoxError> {
37        Ok(s.parse()?)
38    }
39
40    fn display(&self) -> HeaderValue {
41        let val = self.to_string();
42        HeaderValue::dangerous_new_pre_encoded(Self::name(), val.clone(), val)
43    }
44}
45
46impl Display for ContentTransferEncoding {
47    fn fmt(&self, f: &mut FmtFormatter<'_>) -> FmtResult {
48        f.write_str(match *self {
49            Self::SevenBit => "7bit",
50            Self::QuotedPrintable => "quoted-printable",
51            Self::Base64 => "base64",
52            Self::EightBit => "8bit",
53            Self::Binary => "binary",
54        })
55    }
56}
57
58impl FromStr for ContentTransferEncoding {
59    type Err = String;
60    fn from_str(s: &str) -> Result<Self, Self::Err> {
61        match s {
62            "7bit" => Ok(Self::SevenBit),
63            "quoted-printable" => Ok(Self::QuotedPrintable),
64            "base64" => Ok(Self::Base64),
65            "8bit" => Ok(Self::EightBit),
66            "binary" => Ok(Self::Binary),
67            _ => Err(s.into()),
68        }
69    }
70}
71
72#[cfg(test)]
73mod test {
74    use pretty_assertions::assert_eq;
75
76    use super::ContentTransferEncoding;
77    use crate::message::header::{HeaderName, HeaderValue, Headers};
78
79    #[test]
80    fn format_content_transfer_encoding() {
81        let mut headers = Headers::new();
82
83        headers.set(ContentTransferEncoding::SevenBit);
84
85        assert_eq!(headers.to_string(), "Content-Transfer-Encoding: 7bit\r\n");
86
87        headers.set(ContentTransferEncoding::Base64);
88
89        assert_eq!(headers.to_string(), "Content-Transfer-Encoding: base64\r\n");
90    }
91
92    #[test]
93    fn parse_content_transfer_encoding() {
94        let mut headers = Headers::new();
95
96        headers.insert_raw(HeaderValue::new(
97            HeaderName::new_from_ascii_str("Content-Transfer-Encoding"),
98            "7bit".to_owned(),
99        ));
100
101        assert_eq!(
102            headers.get::<ContentTransferEncoding>(),
103            Some(ContentTransferEncoding::SevenBit)
104        );
105
106        headers.insert_raw(HeaderValue::new(
107            HeaderName::new_from_ascii_str("Content-Transfer-Encoding"),
108            "base64".to_owned(),
109        ));
110
111        assert_eq!(
112            headers.get::<ContentTransferEncoding>(),
113            Some(ContentTransferEncoding::Base64)
114        );
115    }
116}