forked from yuzucchii/discord.zig
229 lines
11 KiB
Zig
229 lines
11 KiB
Zig
const Partial = @import("partial.zig").Partial;
|
|
const Snowflake = @import("snowflake.zig").Snowflake;
|
|
const Emoji = @import("emoji.zig").Emoji;
|
|
const ButtonStyles = @import("shared.zig").ButtonStyles;
|
|
const ChannelTypes = @import("shared.zig").ChannelTypes;
|
|
const MessageComponentTypes = @import("shared.zig").MessageComponentTypes;
|
|
|
|
const zjson = @import("../json.zig");
|
|
const std = @import("std");
|
|
|
|
/// https://discord.com/developers/docs/interactions/message-components#buttons
|
|
pub const Button = struct {
|
|
/// 2 for a button
|
|
type: MessageComponentTypes,
|
|
/// A button style
|
|
style: ButtonStyles,
|
|
/// Text that appears on the button; max 80 characters
|
|
label: ?[]const u8,
|
|
/// name, id, and animated
|
|
emoji: Partial(Emoji),
|
|
/// Developer-defined identifier for the button; max 100 characters
|
|
custom_id: ?[]const u8,
|
|
/// Identifier for a purchasable SKU, only available when using premium-style buttons
|
|
sku_id: ?Snowflake,
|
|
/// URL for link-style buttons
|
|
url: ?[]const u8,
|
|
/// Whether the button is disabled (defaults to false)
|
|
disabled: ?bool,
|
|
};
|
|
|
|
pub const SelectOption = struct {
|
|
/// User-facing name of the option; max 100 characters
|
|
label: []const u8,
|
|
/// Dev-defined value of the option; max 100 characters
|
|
value: []const u8,
|
|
/// Additional description of the option; max 100 characters
|
|
description: ?[]const u8,
|
|
/// id, name, and animated
|
|
emoji: ?Partial(Emoji),
|
|
/// Will show this option as selected by default
|
|
default: ?bool,
|
|
};
|
|
|
|
pub const DefaultValue = struct {
|
|
/// ID of a user, role, or channel
|
|
id: Snowflake,
|
|
/// Type of value that id represents. Either "user", "role", or "channel"
|
|
type: union(enum) { user, role, channel },
|
|
};
|
|
|
|
/// https://discord.com/developers/docs/interactions/message-components#select-menus
|
|
pub const SelectMenuString = struct {
|
|
/// Type of select menu component (text: 3, user: 5, role: 6, mentionable: 7, channels: 8)
|
|
type: MessageComponentTypes,
|
|
/// ID for the select menu; max 100 characters
|
|
custom_id: []const u8,
|
|
/// Specified choices in a select menu (only required and available for string selects (type 3); max 25
|
|
/// * options is required for string select menus (component type 3), and unavailable for all other select menu components.
|
|
options: ?[]SelectOption,
|
|
/// Placeholder text if nothing is selected; max 150 characters
|
|
placeholder: ?[]const u8,
|
|
/// Minimum number of items that must be chosen (defaults to 1); min 0, max 25
|
|
min_values: ?usize,
|
|
/// Maximum number of items that can be chosen (defaults to 1); max 25
|
|
max_values: ?usize,
|
|
/// Whether select menu is disabled (defaults to false)
|
|
disabled: ?bool,
|
|
};
|
|
|
|
/// https://discord.com/developers/docs/interactions/message-components#select-menus
|
|
pub const SelectMenuUsers = struct {
|
|
/// Type of select menu component (text: 3, user: 5, role: 6, mentionable: 7, channels: 8)
|
|
type: MessageComponentTypes,
|
|
/// ID for the select menu; max 100 characters
|
|
custom_id: []const u8,
|
|
/// Placeholder text if nothing is selected; max 150 characters
|
|
placeholder: ?[]const u8,
|
|
/// List of default values for auto-populated select menu components; number of default values must be in the range defined by min_values and max_values
|
|
/// *** default_values is only available for auto-populated select menu components, which include user (5), role (6), mentionable (7), and channel (8) components.
|
|
default_values: ?[]DefaultValue,
|
|
/// Minimum number of items that must be chosen (defaults to 1); min 0, max 25
|
|
min_values: ?usize,
|
|
/// Maximum number of items that can be chosen (defaults to 1); max 25
|
|
max_values: ?usize,
|
|
/// Whether select menu is disabled (defaults to false)
|
|
disabled: ?bool,
|
|
};
|
|
|
|
/// https://discord.com/developers/docs/interactions/message-components#select-menus
|
|
pub const SelectMenuRoles = struct {
|
|
/// Type of select menu component (text: 3, user: 5, role: 6, mentionable: 7, channels: 8)
|
|
type: MessageComponentTypes,
|
|
/// ID for the select menu; max 100 characters
|
|
custom_id: []const u8,
|
|
/// Placeholder text if nothing is selected; max 150 characters
|
|
placeholder: ?[]const u8,
|
|
/// List of default values for auto-populated select menu components; number of default values must be in the range defined by min_values and max_values
|
|
/// *** default_values is only available for auto-populated select menu components, which include user (5), role (6), mentionable (7), and channel (8) components.
|
|
default_values: ?[]DefaultValue,
|
|
/// Minimum number of items that must be chosen (defaults to 1); min 0, max 25
|
|
min_values: ?usize,
|
|
/// Maximum number of items that can be chosen (defaults to 1); max 25
|
|
max_values: ?usize,
|
|
/// Whether select menu is disabled (defaults to false)
|
|
disabled: ?bool,
|
|
};
|
|
|
|
/// https://discord.com/developers/docs/interactions/message-components#select-menus
|
|
pub const SelectMenuUsersAndRoles = struct {
|
|
/// Type of select menu component (text: 3, user: 5, role: 6, mentionable: 7, channels: 8)
|
|
type: MessageComponentTypes,
|
|
/// ID for the select menu; max 100 characters
|
|
custom_id: []const u8,
|
|
/// Placeholder text if nothing is selected; max 150 characters
|
|
placeholder: ?[]const u8,
|
|
/// List of default values for auto-populated select menu components; number of default values must be in the range defined by min_values and max_values
|
|
/// *** default_values is only available for auto-populated select menu components, which include user (5), role (6), mentionable (7), and channel (8) components.
|
|
default_values: ?[]DefaultValue,
|
|
/// Minimum number of items that must be chosen (defaults to 1); min 0, max 25
|
|
min_values: ?usize,
|
|
/// Maximum number of items that can be chosen (defaults to 1); max 25
|
|
max_values: ?usize,
|
|
/// Whether select menu is disabled (defaults to false)
|
|
disabled: ?bool,
|
|
};
|
|
|
|
/// https://discord.com/developers/docs/interactions/message-components#select-menus
|
|
pub const SelectMenuChannels = struct {
|
|
/// Type of select menu component (text: 3, user: 5, role: 6, mentionable: 7, channels: 8)
|
|
type: MessageComponentTypes,
|
|
/// ID for the select menu; max 100 characters
|
|
custom_id: []const u8,
|
|
/// List of channel types to include in the channel select component (type 8)
|
|
/// ** channel_types can only be used for channel select menu components.
|
|
channel_types: ?[]ChannelTypes,
|
|
/// Placeholder text if nothing is selected; max 150 characters
|
|
placeholder: ?[]const u8,
|
|
/// List of default values for auto-populated select menu components; number of default values must be in the range defined by min_values and max_values
|
|
/// *** default_values is only available for auto-populated select menu components, which include user (5), role (6), mentionable (7), and channel (8) components.
|
|
default_values: ?[]DefaultValue,
|
|
/// Minimum number of items that must be chosen (defaults to 1); min 0, max 25
|
|
min_values: ?usize,
|
|
/// Maximum number of items that can be chosen (defaults to 1); max 25
|
|
max_values: ?usize,
|
|
/// Whether select menu is disabled (defaults to false)
|
|
disabled: ?bool,
|
|
};
|
|
|
|
pub const SelectMenu = union(MessageComponentTypes) {
|
|
SelectMenu: SelectMenuString,
|
|
SelectMenuUsers: SelectMenuUsers,
|
|
SelectMenuRoles: SelectMenuRoles,
|
|
SelectMenuUsersAndRoles: SelectMenuUsersAndRoles,
|
|
SelectMenuChannels: SelectMenuChannels,
|
|
|
|
pub fn json(allocator: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
|
if (!value.is(.object))
|
|
@panic("coulnd't match against non-object type");
|
|
|
|
switch (value.object.get("type") orelse @panic("couldn't find property `type`")) {
|
|
.number => |num| return switch (@as(MessageComponentTypes, @enumFromInt(num.integer))) {
|
|
.SelectMenu => .{ .SelectMenu = try zjson.parseInto(SelectMenuString, allocator, value) },
|
|
.SelectMenuUsers => .{ .SelectMenuUsers = try zjson.parseInto(SelectMenuUsers, allocator, value) },
|
|
.SelectMenuRoles => .{ .SelectMenuRoles = try zjson.parseInto(SelectMenuRoles, allocator, value) },
|
|
.SelectMenuUsersAndRoles => .{ .SelectMenuUsersAndRoles = try zjson.parseInto(SelectMenuUsersAndRoles, allocator, value) },
|
|
.SelectMenuChannels => .{ .SelectMenuChannels = try zjson.parseInto(SelectMenuChannels, allocator, value) },
|
|
},
|
|
else => @panic("got type but couldn't match against non enum member `type`"),
|
|
}
|
|
unreachable;
|
|
}
|
|
};
|
|
|
|
pub const InputTextStyles = enum(u4) {
|
|
Short = 1,
|
|
Paragraph,
|
|
};
|
|
|
|
pub const InputText = struct {
|
|
/// 4 for a text input
|
|
type: MessageComponentTypes,
|
|
/// Developer-defined identifier for the input; max 100 characters
|
|
custom_id: []const u8,
|
|
/// The Text Input Style
|
|
style: InputTextStyles,
|
|
/// Label for this component; max 45 characters
|
|
label: []const u8,
|
|
/// Minimum input length for a text input; min 0, max 4000
|
|
min_length: ?usize,
|
|
/// Maximum input length for a text input; min 1, max 4000
|
|
max_length: ?usize,
|
|
/// Whether this component is required to be filled (defaults to true)
|
|
required: ?bool,
|
|
/// Pre-filled value for this component; max 4000 characters
|
|
value: ?[]const u8,
|
|
/// Custom placeholder text if the input is empty; max 100 characters
|
|
placeholder: ?[]const u8,
|
|
};
|
|
|
|
pub const MessageComponent = union(MessageComponentTypes) {
|
|
ActionRow: []MessageComponent,
|
|
Button: Button,
|
|
SelectMenu: SelectMenuString,
|
|
InputText: InputText,
|
|
SelectMenuUsers: SelectMenuUsers,
|
|
SelectMenuRoles: SelectMenuRoles,
|
|
SelectMenuUsersAndRoles: SelectMenuUsersAndRoles,
|
|
SelectMenuChannels: SelectMenuChannels,
|
|
|
|
pub fn json(allocator: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
|
if (!value.is(.object))
|
|
@panic("coulnd't match against non-object type");
|
|
|
|
switch (value.object.get("type") orelse @panic("couldn't find property `type`")) {
|
|
.number => |num| return switch (@as(MessageComponentTypes, @enumFromInt(num.integer))) {
|
|
.ActionRow => .{ .ActionRow = try zjson.parseInto([]MessageComponent, allocator, value) },
|
|
.Button => .{ .Button = try zjson.parseInto(Button, allocator, value) },
|
|
.SelectMenu => .{ .SelectMenu = try zjson.parseInto(SelectMenuString, allocator, value) },
|
|
.InputText => .{ .InputText = try zjson.parseInto(InputText, allocator, value) },
|
|
.SelectMenuUsers => .{ .SelectMenuUsers = try zjson.parseInto(SelectMenuUsers, allocator, value) },
|
|
.SelectMenuRoles => .{ .SelectMenuRoles = try zjson.parseInto(SelectMenuRoles, allocator, value) },
|
|
.SelectMenuUsersAndRoles => .{ .SelectMenuUsersAndRoles = try zjson.parseInto(SelectMenuUsersAndRoles, allocator, value) },
|
|
.SelectMenuChannels => .{ .SelectMenuChannels = try zjson.parseInto(SelectMenuChannels, allocator, value) },
|
|
},
|
|
else => @panic("got type but couldn't match against non enum member `type`"),
|
|
}
|
|
}
|
|
};
|