Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 23 additions & 31 deletions src/builder/create_attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,10 @@ impl<'a> ImageData<'a> {
}
}

#[derive(Clone, Debug, Serialize)]
struct ExistingAttachment {
id: AttachmentId,
}

#[derive(Clone, Debug)]
enum NewOrExisting<'a> {
enum EditAttachmentsInner<'a> {
New(CreateAttachment<'a>),
Existing(ExistingAttachment),
Existing(AttachmentId),
}

/// You can add new attachments and edit existing ones using this builder.
Expand Down Expand Up @@ -242,7 +237,7 @@ enum NewOrExisting<'a> {
#[derive(Default, Debug, Clone)]
#[must_use]
pub struct EditAttachments<'a> {
new_and_existing_attachments: Vec<NewOrExisting<'a>>,
inner: Vec<EditAttachmentsInner<'a>>,
}

impl<'a> EditAttachments<'a> {
Expand All @@ -266,15 +261,7 @@ impl<'a> EditAttachments<'a> {
/// Discord will throw an error!**
pub fn keep_all(msg: &Message) -> Self {
Self {
new_and_existing_attachments: msg
.attachments
.iter()
.map(|a| {
NewOrExisting::Existing(ExistingAttachment {
id: a.id,
})
})
.collect(),
inner: msg.attachments.iter().map(|a| EditAttachmentsInner::Existing(a.id)).collect(),
}
}

Expand All @@ -283,9 +270,7 @@ impl<'a> EditAttachments<'a> {
///
/// Opposite of [`Self::remove`].
pub fn keep(mut self, id: AttachmentId) -> Self {
self.new_and_existing_attachments.push(NewOrExisting::Existing(ExistingAttachment {
id,
}));
self.inner.push(EditAttachmentsInner::Existing(id));
self
}

Expand All @@ -294,28 +279,28 @@ impl<'a> EditAttachments<'a> {
///
/// Opposite of [`Self::keep`].
pub fn remove(mut self, id: AttachmentId) -> Self {
self.new_and_existing_attachments.retain(|a| match a {
NewOrExisting::Existing(a) => a.id != id,
NewOrExisting::New(_) => true,
self.inner.retain(|a| match a {
EditAttachmentsInner::Existing(existing_id) => *existing_id != id,
EditAttachmentsInner::New(_) => true,
});
self
}

/// Adds a new attachment to the attachment list.
#[expect(clippy::should_implement_trait)] // Clippy thinks add == std::ops::Add::add
pub fn add(mut self, attachment: CreateAttachment<'a>) -> Self {
self.new_and_existing_attachments.push(NewOrExisting::New(attachment));
self.inner.push(EditAttachmentsInner::New(attachment));
self
}

/// Clones all new attachments into a new Vec, keeping only data and filename, because those
/// are needed for the multipart form data.
#[cfg(feature = "http")]
pub(crate) fn new_attachments(&self) -> Vec<CreateAttachment<'a>> {
self.new_and_existing_attachments
self.inner
.iter()
.filter_map(|attachment| {
if let NewOrExisting::New(attachment) = &attachment {
if let EditAttachmentsInner::New(attachment) = &attachment {
Some(attachment.clone())
} else {
None
Expand All @@ -334,14 +319,19 @@ impl Serialize for EditAttachments<'_> {
description: &'a Option<Cow<'a, str>>,
}

#[derive(Serialize)]
struct ExistingAttachment {
id: AttachmentId,
}

// Instead of an `AttachmentId`, the `id` field for new attachments corresponds to the
// index of the new attachment in the multipart payload. The attachment data will be
// labeled with `files[{id}]` in the multipart body. See `Multipart::build_form`.
let mut id = 0;
let mut seq = serializer.serialize_seq(Some(self.new_and_existing_attachments.len()))?;
for attachment in &self.new_and_existing_attachments {
let mut seq = serializer.serialize_seq(Some(self.inner.len()))?;
for attachment in &self.inner {
match attachment {
NewOrExisting::New(new_attachment) => {
EditAttachmentsInner::New(new_attachment) => {
let attachment = NewAttachment {
id,
filename: &new_attachment.filename,
Expand All @@ -350,8 +340,10 @@ impl Serialize for EditAttachments<'_> {
id += 1;
seq.serialize_element(&attachment)?;
},
NewOrExisting::Existing(existing_attachment) => {
seq.serialize_element(existing_attachment)?;
EditAttachmentsInner::Existing(id) => {
seq.serialize_element(&ExistingAttachment {
id: *id,
})?;
},
}
}
Expand Down