mail_core/resource/
data.rs1use std::{
2 sync::Arc,
3 default::Default,
4 ops::{Deref, DerefMut}
5};
6
7#[cfg(feature="serde")]
8use serde::{
9 Serialize, Deserialize,
10 ser::{Serializer},
11 de::{Deserializer}
12};
13
14use internals::bind::{base64, quoted_printable};
15use headers::header_components::{
16 MediaType,
17 FileMeta,
18 TransferEncoding,
19 ContentId
20};
21
22
23
24#[derive(Debug, Clone)]
41#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
42pub struct Metadata {
43 #[cfg_attr(feature="serde", serde(flatten))]
45 pub file_meta: FileMeta,
46
47 pub media_type: MediaType,
49
50 pub content_id: ContentId
52}
53
54impl Deref for Metadata {
55 type Target = FileMeta;
56
57 fn deref(&self) -> &Self::Target {
58 &self.file_meta
59 }
60}
61
62impl DerefMut for Metadata {
63 fn deref_mut(&mut self) -> &mut Self::Target {
64 &mut self.file_meta
65 }
66}
67
68#[derive(Debug, Clone)]
83#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
84pub struct Data {
85 #[cfg_attr(feature="serde", serde(with="arc_buffer_serde"))]
86 buffer: Arc<[u8]>,
87 #[cfg_attr(feature="serde", serde(flatten))]
88 #[cfg_attr(feature="serde", serde(with="arc_serde"))]
89 meta: Arc<Metadata>
90}
91
92
93impl Data {
94
95 pub fn new(
97 buffer: impl Into<Arc<[u8]>>,
98 meta: impl Into<Arc<Metadata>>
99 ) -> Self {
100 Data {
101 buffer: buffer.into(),
102 meta: meta.into()
103 }
104 }
105
106 pub fn plain_text(text: impl Into<String>, cid: ContentId) -> Data {
107 let text = text.into();
108 let buf = text.into_bytes();
109 let meta = Metadata {
110 file_meta: Default::default(),
111 media_type: MediaType::parse("text/plain; charset=utf-8").unwrap(),
112 content_id: cid
113 };
114 Self::new(buf, meta)
115 }
116
117 pub fn buffer(&self) -> &Arc<[u8]> {
119 &self.buffer
120 }
121
122 pub fn metadata(&self) -> &Arc<Metadata> {
124 &self.meta
125 }
126
127 pub fn file_meta(&self) -> &FileMeta {
129 &self.meta.file_meta
130 }
131
132 pub fn media_type(&self) -> &MediaType {
134 &self.meta.media_type
135 }
136
137 pub fn content_id(&self) -> &ContentId {
139 &self.meta.content_id
140 }
141
142 #[inline(always)]
152 pub fn transfer_encode(
153 &self,
154 encoding_hint: TransferEncodingHint,
155 ) -> EncData {
156 transfer_encode(self, encoding_hint)
159 }
160}
161
162#[derive(Debug, Clone)]
169#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
170pub struct EncData {
171 #[cfg_attr(feature="serde", serde(with="arc_buffer_serde"))]
172 buffer: Arc<[u8]>,
173 #[cfg_attr(feature="serde", serde(flatten))]
174 #[cfg_attr(feature="serde", serde(with="arc_serde"))]
175 meta: Arc<Metadata>,
176 encoding: TransferEncoding
177}
178
179impl EncData {
180
181 pub(crate) fn new(
189 buffer: impl Into<Arc<[u8]>>,
190 meta: impl Into<Arc<Metadata>>,
191 encoding: TransferEncoding
192 ) -> Self {
193 EncData {
194 buffer: buffer.into(),
195 meta: meta.into(),
196 encoding
197 }
198 }
199
200 pub fn transfer_encoded_buffer(&self) -> &Arc<[u8]> {
202 &self.buffer
203 }
204
205 pub fn metadata(&self) -> &Arc<Metadata> {
207 &self.meta
208 }
209
210 pub fn file_meta(&self) -> &FileMeta {
212 &self.meta.file_meta
213 }
214
215 pub fn media_type(&self) -> &MediaType {
217 &self.meta.media_type
218 }
219
220
221 pub fn encoding(&self) -> TransferEncoding {
223 self.encoding
224 }
225
226 pub fn content_id(&self) -> &ContentId {
240 &self.meta.content_id
241 }
242}
243
244#[derive(Debug, PartialEq)]
246#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
247pub enum TransferEncodingHint {
248 UseBase64,
250
251 UseQuotedPrintable,
253
254 NoHint,
264
265 #[cfg_attr(feature="serde", serde(skip))]
266 #[doc(hidden)]
267 __NonExhaustive { }
268}
269
270impl Default for TransferEncodingHint {
271 fn default() -> Self {
272 TransferEncodingHint::UseBase64
273 }
274}
275
276fn transfer_encode(
287 data: &Data,
288 encoding_hint: TransferEncodingHint,
289) -> EncData {
290 use self::TransferEncodingHint::*;
291
292 match encoding_hint {
293 UseQuotedPrintable => tenc_quoted_printable(data),
294 UseBase64 | NoHint => tenc_base64(data),
295 __NonExhaustive { .. } => panic!("__NonExhaustive encoding should not be passed to any place")
296 }
297}
298
299fn tenc_base64(data: &Data) -> EncData {
300 let enc_data = base64::normal_encode(data.buffer())
301 .into_bytes();
302
303 EncData::new(enc_data, data.metadata().clone(),
304 TransferEncoding::Base64)
305}
306
307fn tenc_quoted_printable(data: &Data) -> EncData {
308 let enc_data = quoted_printable::normal_encode(data.buffer())
309 .into_bytes();
310
311 EncData::new(enc_data, data.metadata().clone(),
312 TransferEncoding::QuotedPrintable)
313}
314
315
316#[cfg(feature="serde")]
317mod arc_buffer_serde {
318 use super::*;
319
320 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Arc<[u8]>, D::Error>
321 where D: Deserializer<'de>
322 {
323 let bytes = <Vec<u8>>::deserialize(deserializer)?;
324 Ok(bytes.into())
325 }
326
327 pub(crate) fn serialize<S>(data: &Arc<[u8]>, serializer: S) -> Result<S::Ok, S::Error>
328 where S: Serializer
329 {
330 serializer.serialize_bytes(data)
331 }
332}
333
334#[cfg(feature="serde")]
335mod arc_serde {
336 use super::*;
337
338 pub(crate) fn deserialize<'de, OUT, D>(deserializer: D) -> Result<Arc<OUT>, D::Error>
339 where D: Deserializer<'de>, OUT: Deserialize<'de>
340 {
341 let value = OUT::deserialize(deserializer)?;
342 Ok(Arc::new(value))
343 }
344
345 pub(crate) fn serialize<S, IN>(data: &Arc<IN>, serializer: S) -> Result<S::Ok, S::Error>
346 where S: Serializer, IN: Serialize
347 {
348 IN::serialize(&**data, serializer)
349 }
350}