From e551431d72838be8a514c417ea98458e6602bdfe Mon Sep 17 00:00:00 2001 From: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Date: Wed, 3 Aug 2022 16:44:30 +0300 Subject: [PATCH] Max/Min length fields for ApplicationCommandOption (#2379) * implement max/min length fields for ApplicationCommandOption * fix badly formed xml comments --- .../Interactions/ApplicationCommandOption.cs | 10 ++++ .../Interactions/IApplicationCommandOption.cs | 10 ++++ .../SlashCommands/SlashCommandBuilder.cs | 51 +++++++++++++++++-- .../Attributes/MaxLengthAttribute.cs | 25 +++++++++ .../Attributes/MinLengthAttribute.cs | 25 +++++++++ .../Builders/ModuleClassBuilder.cs | 6 +++ .../SlashCommandParameterBuilder.cs | 36 +++++++++++++ .../Parameters/SlashCommandParameterInfo.cs | 12 +++++ .../Utilities/ApplicationCommandRestUtil.cs | 12 ++++- .../API/Common/ApplicationCommandOption.cs | 10 ++++ .../RestApplicationCommandOption.cs | 9 ++++ .../SocketApplicationCommandOption.cs | 9 ++++ 12 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 src/Discord.Net.Interactions/Attributes/MaxLengthAttribute.cs create mode 100644 src/Discord.Net.Interactions/Attributes/MinLengthAttribute.cs diff --git a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs index 5857bac81..5e4f6a81d 100644 --- a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs +++ b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs @@ -81,6 +81,16 @@ namespace Discord /// public double? MaxValue { get; set; } + /// + /// Gets or sets the minimum allowed length for a string input. + /// + public int? MinLength { get; set; } + + /// + /// Gets or sets the maximum allowed length for a string input. + /// + public int? MaxLength { get; set; } + /// /// Gets or sets the choices for string and int types for the user to pick from. /// diff --git a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs index 72554fc98..c0a752fdc 100644 --- a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs +++ b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs @@ -47,6 +47,16 @@ namespace Discord /// double? MaxValue { get; } + /// + /// Gets the minimum allowed length for a string input. + /// + int? MinLength { get; } + + /// + /// Gets the maximum allowed length for a string input. + /// + int? MaxLength { get; } + /// /// Gets the choices for string and int types for the user to pick from. /// diff --git a/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs index d7d086762..bf22d4e3a 100644 --- a/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs @@ -196,7 +196,7 @@ namespace Discord /// The current builder. public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType type, string description, bool? isRequired = null, bool? isDefault = null, bool isAutocomplete = false, double? minValue = null, double? maxValue = null, - List options = null, List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) + int? minLength = null, int? maxLength = null, List options = null, List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) { Preconditions.Options(name, description); @@ -222,6 +222,8 @@ namespace Discord ChannelTypes = channelTypes, MinValue = minValue, MaxValue = maxValue, + MinLength = minLength, + MaxLength = maxLength, }; return AddOption(option); @@ -354,6 +356,16 @@ namespace Discord /// public double? MaxValue { get; set; } + /// + /// Gets or sets the minimum allowed length for a string input. + /// + public int? MinLength { get; set; } + + /// + /// Gets or sets the maximum allowed length for a string input. + /// + public int? MaxLength { get; set; } + /// /// Gets or sets the choices for string and int types for the user to pick from. /// @@ -377,6 +389,7 @@ namespace Discord { bool isSubType = Type == ApplicationCommandOptionType.SubCommandGroup; bool isIntType = Type == ApplicationCommandOptionType.Integer; + bool isStrType = Type == ApplicationCommandOptionType.String; if (isSubType && (Options == null || !Options.Any())) throw new InvalidOperationException("SubCommands/SubCommandGroups must have at least one option"); @@ -390,6 +403,12 @@ namespace Discord if (isIntType && MaxValue != null && MaxValue % 1 != 0) throw new InvalidOperationException("MaxValue cannot have decimals on Integer command options."); + if(isStrType && MinLength is not null && MinLength < 0) + throw new InvalidOperationException("MinLength cannot be smaller than 0."); + + if (isStrType && MaxLength is not null && MaxLength < 1) + throw new InvalidOperationException("MaxLength cannot be smaller than 1."); + return new ApplicationCommandOptionProperties { Name = Name, @@ -404,7 +423,9 @@ namespace Discord IsAutocomplete = IsAutocomplete, ChannelTypes = ChannelTypes, MinValue = MinValue, - MaxValue = MaxValue + MaxValue = MaxValue, + MinLength = MinLength, + MaxLength = MaxLength, }; } @@ -425,7 +446,7 @@ namespace Discord /// The current builder. public SlashCommandOptionBuilder AddOption(string name, ApplicationCommandOptionType type, string description, bool? isRequired = null, bool isDefault = false, bool isAutocomplete = false, double? minValue = null, double? maxValue = null, - List options = null, List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) + int? minLength = null, int? maxLength = null, List options = null, List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) { Preconditions.Options(name, description); @@ -447,6 +468,8 @@ namespace Discord IsAutocomplete = isAutocomplete, MinValue = minValue, MaxValue = maxValue, + MinLength = minLength, + MaxLength = maxLength, Options = options, Type = type, Choices = (choices ?? Array.Empty()).ToList(), @@ -669,6 +692,28 @@ namespace Discord return this; } + /// + /// Sets the current builders min length field. + /// + /// The value to set. + /// The current builder. + public SlashCommandOptionBuilder WithMinLength(int length) + { + MinLength = length; + return this; + } + + /// + /// Sets the current builders max length field. + /// + /// The value to set. + /// The current builder. + public SlashCommandOptionBuilder WithMaxLength(int lenght) + { + MaxLength = lenght; + return this; + } + /// /// Sets the current type of this builder. /// diff --git a/src/Discord.Net.Interactions/Attributes/MaxLengthAttribute.cs b/src/Discord.Net.Interactions/Attributes/MaxLengthAttribute.cs new file mode 100644 index 000000000..1099e7d92 --- /dev/null +++ b/src/Discord.Net.Interactions/Attributes/MaxLengthAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Discord.Interactions +{ + /// + /// Sets the maximum length allowed for a string type parameter. + /// + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] + public class MaxLengthAttribute : Attribute + { + /// + /// Gets the maximum length allowed for a string type parameter. + /// + public int Length { get; } + + /// + /// Sets the maximum length allowed for a string type parameter. + /// + /// Maximum string length allowed. + public MaxLengthAttribute(int lenght) + { + Length = lenght; + } + } +} diff --git a/src/Discord.Net.Interactions/Attributes/MinLengthAttribute.cs b/src/Discord.Net.Interactions/Attributes/MinLengthAttribute.cs new file mode 100644 index 000000000..7d0b0fd63 --- /dev/null +++ b/src/Discord.Net.Interactions/Attributes/MinLengthAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Discord.Interactions +{ + /// + /// Sets the minimum length allowed for a string type parameter. + /// + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] + public class MinLengthAttribute : Attribute + { + /// + /// Gets the minimum length allowed for a string type parameter. + /// + public int Length { get; } + + /// + /// Sets the minimum length allowed for a string type parameter. + /// + /// Minimum string length allowed. + public MinLengthAttribute(int lenght) + { + Length = lenght; + } + } +} diff --git a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs index 1bbdfcc4a..35126a674 100644 --- a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs +++ b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs @@ -463,6 +463,12 @@ namespace Discord.Interactions.Builders case MinValueAttribute minValue: builder.MinValue = minValue.Value; break; + case MinLengthAttribute minLength: + builder.MinLength = minLength.Length; + break; + case MaxLengthAttribute maxLength: + builder.MaxLength = maxLength.Length; + break; case ComplexParameterAttribute complexParameter: { builder.IsComplexParameter = true; diff --git a/src/Discord.Net.Interactions/Builders/Parameters/SlashCommandParameterBuilder.cs b/src/Discord.Net.Interactions/Builders/Parameters/SlashCommandParameterBuilder.cs index d600c9cc7..6f8038cef 100644 --- a/src/Discord.Net.Interactions/Builders/Parameters/SlashCommandParameterBuilder.cs +++ b/src/Discord.Net.Interactions/Builders/Parameters/SlashCommandParameterBuilder.cs @@ -28,6 +28,16 @@ namespace Discord.Interactions.Builders /// public double? MinValue { get; set; } + /// + /// Gets or sets the minimum length allowed for a string type parameter. + /// + public int? MinLength { get; set; } + + /// + /// Gets or sets the maximum length allowed for a string type parameter. + /// + public int? MaxLength { get; set; } + /// /// Gets a collection of the choices of this command. /// @@ -125,6 +135,32 @@ namespace Discord.Interactions.Builders return this; } + /// + /// Sets . + /// + /// New value of the . + /// + /// The builder instance. + /// + public SlashCommandParameterBuilder WithMinLength(int length) + { + MinLength = length; + return this; + } + + /// + /// Sets . + /// + /// New value of the . + /// + /// The builder instance. + /// + public SlashCommandParameterBuilder WithMaxLength(int length) + { + MaxLength = length; + return this; + } + /// /// Adds parameter choices to . /// diff --git a/src/Discord.Net.Interactions/Info/Parameters/SlashCommandParameterInfo.cs b/src/Discord.Net.Interactions/Info/Parameters/SlashCommandParameterInfo.cs index 8702d69f7..0bce42186 100644 --- a/src/Discord.Net.Interactions/Info/Parameters/SlashCommandParameterInfo.cs +++ b/src/Discord.Net.Interactions/Info/Parameters/SlashCommandParameterInfo.cs @@ -38,6 +38,16 @@ namespace Discord.Interactions /// public double? MaxValue { get; } + /// + /// Gets the minimum length allowed for a string type parameter. + /// + public int? MinLength { get; } + + /// + /// Gets the maximum length allowed for a string type parameter. + /// + public int? MaxLength { get; } + /// /// Gets the that will be used to convert the incoming into /// . @@ -86,6 +96,8 @@ namespace Discord.Interactions Description = builder.Description; MaxValue = builder.MaxValue; MinValue = builder.MinValue; + MinLength = builder.MinLength; + MaxLength = builder.MaxLength; IsComplexParameter = builder.IsComplexParameter; IsAutocomplete = builder.Autocomplete; Choices = builder.Choices.ToImmutableArray(); diff --git a/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs b/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs index e4b6f893c..409c0e796 100644 --- a/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs +++ b/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs @@ -23,7 +23,9 @@ namespace Discord.Interactions ChannelTypes = parameterInfo.ChannelTypes?.ToList(), IsAutocomplete = parameterInfo.IsAutocomplete, MaxValue = parameterInfo.MaxValue, - MinValue = parameterInfo.MinValue + MinValue = parameterInfo.MinValue, + MinLength = parameterInfo.MinLength, + MaxLength = parameterInfo.MaxLength, }; parameterInfo.TypeConverter.Write(props, parameterInfo); @@ -209,7 +211,13 @@ namespace Discord.Interactions Name = x.Name, Value = x.Value }).ToList(), - Options = commandOption.Options?.Select(x => x.ToApplicationCommandOptionProps()).ToList() + Options = commandOption.Options?.Select(x => x.ToApplicationCommandOptionProps()).ToList(), + MaxLength = commandOption.MaxLength, + MinLength = commandOption.MinLength, + MaxValue = commandOption.MaxValue, + MinValue = commandOption.MinValue, + IsAutocomplete = commandOption.IsAutocomplete.GetValueOrDefault(), + ChannelTypes = commandOption.ChannelTypes.ToList(), }; public static Modal ToModal(this ModalInfo modalInfo, string customId, Action modifyModal = null) diff --git a/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs b/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs index d703bd46b..fff5730f4 100644 --- a/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs +++ b/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs @@ -38,6 +38,12 @@ namespace Discord.API [JsonProperty("channel_types")] public Optional ChannelTypes { get; set; } + [JsonProperty("min_length")] + public Optional MinLength { get; set; } + + [JsonProperty("max_length")] + public Optional MaxLength { get; set; } + public ApplicationCommandOption() { } public ApplicationCommandOption(IApplicationCommandOption cmd) @@ -56,6 +62,8 @@ namespace Discord.API Default = cmd.IsDefault ?? Optional.Unspecified; MinValue = cmd.MinValue ?? Optional.Unspecified; MaxValue = cmd.MaxValue ?? Optional.Unspecified; + MinLength = cmd.MinLength ?? Optional.Unspecified; + MaxLength = cmd.MaxLength ?? Optional.Unspecified; Autocomplete = cmd.IsAutocomplete ?? Optional.Unspecified; Name = cmd.Name; @@ -77,6 +85,8 @@ namespace Discord.API Default = option.IsDefault ?? Optional.Unspecified; MinValue = option.MinValue ?? Optional.Unspecified; MaxValue = option.MaxValue ?? Optional.Unspecified; + MinLength = option.MinLength ?? Optional.Unspecified; + MaxLength = option.MaxLength ?? Optional.Unspecified; ChannelTypes = option.ChannelTypes?.ToArray() ?? Optional.Unspecified; diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs index 86c6019ed..c47080be7 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs @@ -35,6 +35,12 @@ namespace Discord.Rest /// public double? MaxValue { get; private set; } + /// + public int? MinLength { get; private set; } + + /// + public int? MaxLength { get; private set; } + /// /// Gets a collection of s for this command. /// @@ -78,6 +84,9 @@ namespace Discord.Rest if (model.Autocomplete.IsSpecified) IsAutocomplete = model.Autocomplete.Value; + MinLength = model.MinLength.ToNullable(); + MaxLength = model.MaxLength.ToNullable(); + Options = model.Options.IsSpecified ? model.Options.Value.Select(Create).ToImmutableArray() : ImmutableArray.Create(); diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs index 27777749a..478c7cb54 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs @@ -33,6 +33,12 @@ namespace Discord.WebSocket /// public double? MaxValue { get; private set; } + /// + public int? MinLength { get; private set; } + + /// + public int? MaxLength { get; private set; } + /// /// Gets a collection of choices for the user to pick from. /// @@ -72,6 +78,9 @@ namespace Discord.WebSocket IsAutocomplete = model.Autocomplete.ToNullable(); + MinLength = model.MinLength.ToNullable(); + MaxLength = model.MaxLength.ToNullable(); + Choices = model.Choices.IsSpecified ? model.Choices.Value.Select(SocketApplicationCommandChoice.Create).ToImmutableArray() : ImmutableArray.Create();