Skip to content

Commit 049e52a

Browse files
committed
Add support for file upload components
1 parent 82ba01b commit 049e52a

File tree

5 files changed

+82
-2
lines changed

5 files changed

+82
-2
lines changed

src/builder/create_components.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,16 @@ impl<'a> CreateLabel<'a> {
523523
}
524524
}
525525

526+
/// Create a file upload with a specific label.
527+
pub fn file_upload(label: impl Into<Cow<'a, str>>, file_upload: CreateFileUpload<'a>) -> Self {
528+
Self {
529+
kind: ComponentType::Label,
530+
label: label.into(),
531+
description: None,
532+
component: CreateLabelComponent::FileUpload(file_upload),
533+
}
534+
}
535+
526536
/// Sets the description of this component, which will display underneath the label text.
527537
pub fn description(mut self, description: impl Into<Cow<'a, str>>) -> Self {
528538
self.description = Some(description.into());
@@ -537,6 +547,53 @@ impl<'a> CreateLabel<'a> {
537547
enum CreateLabelComponent<'a> {
538548
SelectMenu(CreateSelectMenu<'a>),
539549
InputText(CreateInputText<'a>),
550+
FileUpload(CreateFileUpload<'a>),
551+
}
552+
553+
/// A builder for creating a file upload in a modal.
554+
///
555+
/// [Discord docs](https://discord.com/developers/docs/components/reference#file-upload).
556+
#[derive(Clone, Debug, Serialize)]
557+
#[must_use]
558+
pub struct CreateFileUpload<'a> {
559+
#[serde(rename = "type")]
560+
kind: ComponentType,
561+
custom_id: Cow<'a, str>,
562+
min_values: u8,
563+
max_values: u8,
564+
required: bool,
565+
}
566+
567+
impl<'a> CreateFileUpload<'a> {
568+
/// Creates a builder with the given custom id.
569+
pub fn new(custom_id: impl Into<Cow<'a, str>>) -> Self {
570+
Self {
571+
kind: ComponentType::FileUpload,
572+
custom_id: custom_id.into(),
573+
min_values: 1,
574+
max_values: 1,
575+
required: true,
576+
}
577+
}
578+
579+
/// The minimum number of files that must be uploaded. Must be a number from 0 through 10, and
580+
/// defaults to 1.
581+
pub fn min_values(mut self, min_values: u8) -> Self {
582+
self.min_values = min_values;
583+
self
584+
}
585+
586+
/// The maximum number of files that can be uploaded. Defaults to 1, but can be at most 10.
587+
pub fn max_values(mut self, max_values: u8) -> Self {
588+
self.max_values = max_values;
589+
self
590+
}
591+
592+
// Whether the file upload is required.
593+
pub fn required(mut self, required: bool) -> Self {
594+
self.required = required;
595+
self
596+
}
540597
}
541598

542599
enum_number! {

src/model/application/command_interaction.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,10 @@ pub struct CommandData {
240240
/// The application command type of the triggered application command.
241241
#[serde(rename = "type")]
242242
pub kind: CommandType,
243-
/// The parameters and the given values. The converted objects from the given options.
243+
/// The converted objects from the given options.
244244
#[serde(default)]
245245
pub resolved: CommandDataResolved,
246+
/// The parameters and the given values.
246247
#[serde(default)]
247248
pub options: FixedArray<CommandDataOption>,
248249
/// The Id of the guild the command is registered to.

src/model/application/component.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum_number! {
2828
Separator = 14,
2929
Container = 17,
3030
Label = 18,
31+
FileUpload = 19,
3132
_ => Unknown(u8),
3233
}
3334
}
@@ -299,6 +300,7 @@ pub struct Label {
299300
pub enum LabelComponent {
300301
SelectMenu(SelectMenu),
301302
InputText(InputText),
303+
FileUpload(FileUpload),
302304
}
303305

304306
impl<'de> Deserialize<'de> for LabelComponent {
@@ -323,6 +325,9 @@ impl<'de> Deserialize<'de> for LabelComponent {
323325
ComponentType::InputText => {
324326
Deserialize::deserialize(raw_data).map(LabelComponent::InputText)
325327
},
328+
ComponentType::FileUpload => {
329+
Deserialize::deserialize(raw_data).map(LabelComponent::FileUpload)
330+
},
326331
ComponentType(i) => {
327332
return Err(DeError::custom(format_args!("Unknown component type {i}")));
328333
},
@@ -331,6 +336,20 @@ impl<'de> Deserialize<'de> for LabelComponent {
331336
}
332337
}
333338

339+
/// An interactive component that allows users to upload files in modals.
340+
#[derive(Clone, Debug, Deserialize, Serialize)]
341+
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
342+
#[non_exhaustive]
343+
pub struct FileUpload {
344+
/// Always [`ComponentType::FileUpload`]
345+
#[serde(rename = "type")]
346+
pub kind: ComponentType,
347+
/// Developer-defined identifier for the file upload; max 100 characters
348+
pub custom_id: FixedString,
349+
/// IDs of the uploaded files found in [`ModalInteractionData::resolved`].
350+
pub values: FixedArray<AttachmentId>,
351+
}
352+
334353
/// An action row.
335354
///
336355
/// [Discord docs](https://discord.com/developers/docs/components/reference#action-row).

src/model/application/component_interaction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ pub struct ComponentInteractionData {
315315
/// Type and type-specific data of this component interaction.
316316
#[serde(flatten)]
317317
pub kind: ComponentInteractionDataKind,
318-
/// The parameters and the given values. The converted objects from the given options.
318+
/// The resolved entities from the selected options.
319319
#[serde(default)]
320320
pub resolved: CommandDataResolved,
321321
}

src/model/application/modal_interaction.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,7 @@ pub struct ModalInteractionData {
216216
pub custom_id: FixedString,
217217
/// The components.
218218
pub components: FixedArray<Component>,
219+
/// The resolved entities from the selected options.
220+
#[serde(default)]
221+
pub resolved: CommandDataResolved,
219222
}

0 commit comments

Comments
 (0)