lettre/message/header/
special.rs

1use crate::{
2    message::header::{Header, HeaderName, HeaderValue},
3    BoxError,
4};
5
6/// Message format version, defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-4)
7#[derive(Debug, Copy, Clone, PartialEq, Eq)]
8pub struct MimeVersion {
9    major: u8,
10    minor: u8,
11}
12
13/// MIME version 1.0
14///
15/// Should be used in all MIME messages.
16pub const MIME_VERSION_1_0: MimeVersion = MimeVersion::new(1, 0);
17
18impl MimeVersion {
19    /// Build a new `MimeVersion` header
20    pub const fn new(major: u8, minor: u8) -> Self {
21        MimeVersion { major, minor }
22    }
23
24    /// Get the `major` value of this `MimeVersion` header.
25    #[inline]
26    pub const fn major(self) -> u8 {
27        self.major
28    }
29
30    /// Get the `minor` value of this `MimeVersion` header.
31    #[inline]
32    pub const fn minor(self) -> u8 {
33        self.minor
34    }
35}
36
37impl Header for MimeVersion {
38    fn name() -> HeaderName {
39        HeaderName::new_from_ascii_str("MIME-Version")
40    }
41
42    fn parse(s: &str) -> Result<Self, BoxError> {
43        let mut s = s.split('.');
44
45        let major = s
46            .next()
47            .expect("The first call to next for a Split<char> always succeeds");
48        let minor = s
49            .next()
50            .ok_or_else(|| String::from("MIME-Version header doesn't contain '.'"))?;
51        let major = major.parse()?;
52        let minor = minor.parse()?;
53        Ok(MimeVersion::new(major, minor))
54    }
55
56    fn display(&self) -> HeaderValue {
57        let val = format!("{}.{}", self.major, self.minor);
58        HeaderValue::dangerous_new_pre_encoded(Self::name(), val.clone(), val)
59    }
60}
61
62impl Default for MimeVersion {
63    fn default() -> Self {
64        MIME_VERSION_1_0
65    }
66}
67
68#[cfg(test)]
69mod test {
70    use pretty_assertions::assert_eq;
71
72    use super::{MimeVersion, MIME_VERSION_1_0};
73    use crate::message::header::{HeaderName, HeaderValue, Headers};
74
75    #[test]
76    fn format_mime_version() {
77        let mut headers = Headers::new();
78
79        headers.set(MIME_VERSION_1_0);
80
81        assert_eq!(headers.to_string(), "MIME-Version: 1.0\r\n");
82
83        headers.set(MimeVersion::new(0, 1));
84
85        assert_eq!(headers.to_string(), "MIME-Version: 0.1\r\n");
86    }
87
88    #[test]
89    fn parse_mime_version() {
90        let mut headers = Headers::new();
91
92        headers.insert_raw(HeaderValue::new(
93            HeaderName::new_from_ascii_str("MIME-Version"),
94            "1.0".to_owned(),
95        ));
96
97        assert_eq!(headers.get::<MimeVersion>(), Some(MIME_VERSION_1_0));
98
99        headers.insert_raw(HeaderValue::new(
100            HeaderName::new_from_ascii_str("MIME-Version"),
101            "0.1".to_owned(),
102        ));
103
104        assert_eq!(headers.get::<MimeVersion>(), Some(MimeVersion::new(0, 1)));
105    }
106}