Skip to main content

daaki_imap/types/
body.rs

1//! `BODYSTRUCTURE` types (RFC 3501 Section 7.4.2, RFC 9051 Section 7.5.2).
2//!
3//! Models both single-part and multipart MIME structures as returned by BODYSTRUCTURE
4//! and BODY fetch items.
5
6/// Parsed IMAP BODYSTRUCTURE (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
7#[non_exhaustive]
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub enum BodyStructure {
11    /// A single non-text, non-message part (e.g. image/png, application/pdf)
12    /// (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
13    Basic {
14        /// MIME type (e.g. `"image"`, `"application"`) (RFC 2045 Section 5.1).
15        media_type: String,
16        /// MIME subtype (e.g. `"png"`, `"pdf"`) (RFC 2045 Section 5.1).
17        media_subtype: String,
18        /// MIME content-type parameters (RFC 2045 Section 5.1 / RFC 2231).
19        params: Vec<(String, String)>,
20        /// Content-ID header value (RFC 2045 Section 7).
21        id: Option<String>,
22        /// Content-Description header value (RFC 2045 Section 8).
23        description: Option<String>,
24        /// Content-Transfer-Encoding (RFC 2045 Section 6).
25        encoding: String,
26        /// Body size in octets (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
27        ///
28        /// RFC 3501 and RFC 9051 both define `body-fld-octets` as `number` (u32),
29        /// but stored as `u64` for Postel's-law leniency with servers that send
30        /// larger values.
31        size: u64,
32        // Extension data (may be absent).
33        /// Content-MD5 value (RFC 3501 Section 7.4.2 extension data).
34        md5: Option<String>,
35        /// Content-Disposition (RFC 2183 / RFC 3501 Section 7.4.2 extension data).
36        disposition: Option<ContentDisposition>,
37        /// Body language (RFC 3501 Section 7.4.2 extension data).
38        language: Option<Vec<String>>,
39        /// Body content location (RFC 3501 Section 7.4.2 extension data).
40        location: Option<String>,
41    },
42    /// A `text/*` part (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
43    Text {
44        /// MIME subtype (e.g. `"plain"`, `"html"`) (RFC 2045 Section 5.1).
45        media_subtype: String,
46        /// MIME content-type parameters (RFC 2045 Section 5.1 / RFC 2231).
47        params: Vec<(String, String)>,
48        /// Content-ID header value (RFC 2045 Section 7).
49        id: Option<String>,
50        /// Content-Description header value (RFC 2045 Section 8).
51        description: Option<String>,
52        /// Content-Transfer-Encoding (RFC 2045 Section 6).
53        encoding: String,
54        /// Body size in octets (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
55        ///
56        /// RFC 3501 and RFC 9051 both define `body-fld-octets` as `number` (u32),
57        /// but stored as `u64` for Postel's-law leniency with servers that send
58        /// larger values.
59        size: u64,
60        /// Number of lines in the text body (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
61        ///
62        /// RFC 9051 widens `body-fld-lines` from `number` to `number64`.
63        lines: u64,
64        // Extension data.
65        /// Content-MD5 value (RFC 3501 Section 7.4.2 extension data).
66        md5: Option<String>,
67        /// Content-Disposition (RFC 2183 / RFC 3501 Section 7.4.2 extension data).
68        disposition: Option<ContentDisposition>,
69        /// Body language (RFC 3501 Section 7.4.2 extension data).
70        language: Option<Vec<String>>,
71        /// Body content location (RFC 3501 Section 7.4.2 extension data).
72        location: Option<String>,
73    },
74    /// A `message/rfc822` or `message/global` part — embedded message
75    /// (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
76    Message {
77        /// MIME subtype (`"rfc822"` or `"global"`) (RFC 9051 Section 7.5.2).
78        media_subtype: String,
79        /// MIME content-type parameters (RFC 2045 Section 5.1 / RFC 2231).
80        params: Vec<(String, String)>,
81        /// Content-ID header value (RFC 2045 Section 7).
82        id: Option<String>,
83        /// Content-Description header value (RFC 2045 Section 8).
84        description: Option<String>,
85        /// Content-Transfer-Encoding (RFC 2045 Section 6).
86        encoding: String,
87        /// Body size in octets (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
88        ///
89        /// RFC 3501 and RFC 9051 both define `body-fld-octets` as `number` (u32),
90        /// but stored as `u64` for Postel's-law leniency with servers that send
91        /// larger values.
92        size: u64,
93        /// Envelope of the embedded message (RFC 3501 Section 7.4.2).
94        envelope: Box<super::Envelope>,
95        /// Body structure of the embedded message (RFC 3501 Section 7.4.2).
96        body: Box<Self>,
97        /// Number of lines in the embedded message (RFC 3501 Section 7.4.2 / RFC 9051 Section 7.5.2).
98        ///
99        /// RFC 9051 widens `body-fld-lines` from `number` to `number64`.
100        lines: u64,
101        // Extension data.
102        /// Content-MD5 value (RFC 3501 Section 7.4.2 extension data).
103        md5: Option<String>,
104        /// Content-Disposition (RFC 2183 / RFC 3501 Section 7.4.2 extension data).
105        disposition: Option<ContentDisposition>,
106        /// Body language (RFC 3501 Section 7.4.2 extension data).
107        language: Option<Vec<String>>,
108        /// Body content location (RFC 3501 Section 7.4.2 extension data).
109        location: Option<String>,
110    },
111    /// A `multipart/*` container (RFC 2046 Section 5 / RFC 3501 Section 7.4.2).
112    Multipart {
113        /// Multipart subtype (e.g. `"mixed"`, `"alternative"`) (RFC 2046 Section 5).
114        media_subtype: String,
115        /// Child body parts (RFC 2046 Section 5).
116        bodies: Vec<Self>,
117        // Extension data.
118        /// MIME content-type parameters (RFC 2045 Section 5.1 / RFC 2231).
119        params: Vec<(String, String)>,
120        /// Content-Disposition (RFC 2183 / RFC 3501 Section 7.4.2 extension data).
121        disposition: Option<ContentDisposition>,
122        /// Body language (RFC 3501 Section 7.4.2 extension data).
123        language: Option<Vec<String>>,
124        /// Body content location (RFC 3501 Section 7.4.2 extension data).
125        location: Option<String>,
126    },
127}
128
129/// Content-Disposition from BODYSTRUCTURE extension data (RFC 2183).
130#[non_exhaustive]
131#[derive(Debug, Clone, PartialEq, Eq, Default, Hash)]
132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
133pub struct ContentDisposition {
134    /// Disposition type (e.g. `"inline"`, `"attachment"`) (RFC 2183 Section 2).
135    pub disposition_type: String,
136    /// Disposition parameters (e.g. `("filename", "report.pdf")`)
137    /// (RFC 2183 Section 2 / RFC 2231).
138    pub params: Vec<(String, String)>,
139}
140
141#[cfg(test)]
142#[path = "body_tests.rs"]
143mod tests;