serenity/http/
multipart.rs1use std::borrow::Cow;
2
3use reqwest::multipart::{Form, Part};
4
5use crate::builder::CreateAttachment;
6use crate::internal::prelude::*;
7
8impl CreateAttachment {
9    fn into_part(self) -> Result<Part> {
10        let mut part = Part::bytes(self.data);
11        part = guess_mime_str(part, &self.filename)?;
12        part = part.file_name(self.filename);
13        Ok(part)
14    }
15}
16
17#[derive(Clone, Debug)]
18pub enum MultipartUpload {
19    File(CreateAttachment),
21    Attachments(Vec<CreateAttachment>),
23}
24
25#[derive(Clone, Debug)]
28pub struct Multipart {
29    pub upload: MultipartUpload,
30    pub fields: Vec<(Cow<'static, str>, Cow<'static, str>)>,
33    pub payload_json: Option<String>,
35}
36
37impl Multipart {
38    pub(crate) fn build_form(self) -> Result<Form> {
39        let mut multipart = Form::new();
40
41        match self.upload {
42            MultipartUpload::File(upload_file) => {
43                multipart = multipart.part("file", upload_file.into_part()?);
44            },
45            MultipartUpload::Attachments(attachment_files) => {
46                for file in attachment_files {
47                    multipart = multipart.part(format!("files[{}]", file.id), file.into_part()?);
48                }
49            },
50        }
51
52        for (name, value) in self.fields {
53            multipart = multipart.text(name, value);
54        }
55
56        if let Some(payload_json) = self.payload_json {
57            multipart = multipart.text("payload_json", payload_json);
58        }
59
60        Ok(multipart)
61    }
62}
63
64fn guess_mime_str(part: Part, filename: &str) -> Result<Part> {
65    let mime_type = mime_guess::from_path(filename).first_or_octet_stream();
71    part.mime_str(mime_type.essence_str()).map_err(Into::into)
72}