Skip to content

Commit

Permalink
Support Min and Max values on ApplicationCommandOptions (discord-net#273
Browse files Browse the repository at this point in the history
)

* Support Min and Max values on ApplicationCommandOptions

* Support decimal min/max values

* Docs imrpovments + use ToNullable
  • Loading branch information
CottageDwellingCat authored Nov 10, 2021
1 parent 85b9f4f commit 8e5e360
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ public string Description
/// Gets or sets whether or not this option supports autocomplete.
/// </summary>
public bool Autocomplete { get; set; }

/// <summary>
/// Gets or sets the smallest number value the user can input.
/// </summary>
public double? MinValue { get; set; }

/// <summary>
/// Gets or sets the largest number value the user can input.
/// </summary>
public double? MaxValue { get; set; }

/// <summary>
/// Gets or sets the choices for string and int types for the user to pick from.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ public interface IApplicationCommandOption
/// </summary>
bool? IsRequired { get; }

/// <summary>
/// The smallest number value the user can input.
/// </summary>
double? MinValue { get; }

/// <summary>
/// The largest number value the user can input.
/// </summary>
double? MaxValue { get; }

/// <summary>
/// Choices for string and int types for the user to pick from.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,12 @@ public SlashCommandBuilder WithDefaultPermission(bool value)
/// <param name="options">The options of the option to add.</param>
/// <param name="channelTypes">The allowed channel types for this option.</param>
/// <param name="choices">The choices of this option.</param>
/// <param name="minValue">The smallest number value the user can input.</param>
/// <param name="maxValue">The largest number value the user can input.</param>
/// <returns>The current builder.</returns>
public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType type,
string description, bool? required = null, bool? isDefault = null, bool isAutocomplete = false, List<SlashCommandOptionBuilder> options = null,
List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
string description, bool? required = null, bool? isDefault = null, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
{
// Make sure the name matches the requirements from discord
Preconditions.NotNullOrEmpty(name, nameof(name));
Expand Down Expand Up @@ -189,7 +191,9 @@ public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType t
Type = type,
Autocomplete = isAutocomplete,
Choices = (choices ?? Array.Empty<ApplicationCommandOptionChoiceProperties>()).ToList(),
ChannelTypes = channelTypes
ChannelTypes = channelTypes,
MinValue = minValue,
MaxValue = maxValue,
};

return AddOption(option);
Expand Down Expand Up @@ -321,6 +325,16 @@ public string Description
/// </summary>
public bool Autocomplete { get; set; }

/// <summary>
/// Gets or sets the smallest number value the user can input.
/// </summary>
public double? MinValue { get; set; }

/// <summary>
/// Gets or sets the largest number value the user can input.
/// </summary>
public double? MaxValue { get; set; }

/// <summary>
/// Gets or sets the choices for string and int types for the user to pick from.
/// </summary>
Expand All @@ -343,13 +357,20 @@ public string Description
public ApplicationCommandOptionProperties Build()
{
bool isSubType = Type == ApplicationCommandOptionType.SubCommandGroup;
bool isIntType = Type == ApplicationCommandOptionType.Integer;

if (isSubType && (Options == null || !Options.Any()))
throw new InvalidOperationException("SubCommands/SubCommandGroups must have at least one option");

if (!isSubType && Options != null && Options.Any() && Type != ApplicationCommandOptionType.SubCommand)
throw new InvalidOperationException($"Cannot have options on {Type} type");

if (isIntType && MinValue != null && MinValue % 1 != 0)
throw new InvalidOperationException("MinValue cannot have decimals on Integer command options.");

if (isIntType && MaxValue != null && MaxValue % 1 != 0)
throw new InvalidOperationException("MaxValue cannot have decimals on Integer command options.");

return new ApplicationCommandOptionProperties
{
Name = Name,
Expand All @@ -360,7 +381,9 @@ public ApplicationCommandOptionProperties Build()
Options = Options?.Count > 0 ? Options.Select(x => x.Build()).ToList() : new List<ApplicationCommandOptionProperties>(),
Choices = Choices,
Autocomplete = Autocomplete,
ChannelTypes = ChannelTypes
ChannelTypes = ChannelTypes,
MinValue = MinValue,
MaxValue = MaxValue
};
}

Expand All @@ -376,10 +399,12 @@ public ApplicationCommandOptionProperties Build()
/// <param name="options">The options of the option to add.</param>
/// <param name="channelTypes">The allowed channel types for this option.</param>
/// <param name="choices">The choices of this option.</param>
/// <param name="minValue">The smallest number value the user can input.</param>
/// <param name="maxValue">The largest number value the user can input.</param>
/// <returns>The current builder.</returns>
public SlashCommandOptionBuilder AddOption(string name, ApplicationCommandOptionType type,
string description, bool? required = null, bool isDefault = false, bool isAutocomplete = false, List<SlashCommandOptionBuilder> options = null,
List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
string description, bool? required = null, bool isDefault = false, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
{
// Make sure the name matches the requirements from discord
Preconditions.NotNullOrEmpty(name, nameof(name));
Expand Down Expand Up @@ -407,6 +432,8 @@ public SlashCommandOptionBuilder AddOption(string name, ApplicationCommandOption
Required = required,
Default = isDefault,
Autocomplete = isAutocomplete,
MinValue = minValue,
MaxValue = maxValue,
Options = options,
Type = type,
Choices = (choices ?? Array.Empty<ApplicationCommandOptionChoiceProperties>()).ToList(),
Expand Down Expand Up @@ -561,6 +588,28 @@ public SlashCommandOptionBuilder WithAutocomplete(bool value)
return this;
}

/// <summary>
/// Sets the current builders min value field.
/// </summary>
/// <param name="value">The value to set.</param>
/// <returns>The current builder.</returns>
public SlashCommandOptionBuilder WithMinValue(double value)
{
MinValue = value;
return this;
}

/// <summary>
/// Sets the current builders max value field.
/// </summary>
/// <param name="value">The value to set.</param>
/// <returns>The current builder.</returns>
public SlashCommandOptionBuilder WithMaxValue(double value)
{
MaxValue = value;
return this;
}

/// <summary>
/// Sets the current type of this builder.
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ internal class ApplicationCommandOption
[JsonProperty("autocomplete")]
public Optional<bool> Autocomplete { get; set; }

[JsonProperty("min_value")]
public Optional<double> MinValue { get; set; }

[JsonProperty("max_value")]
public Optional<double> MaxValue { get; set; }

[JsonProperty("channel_types")]
public Optional<ChannelType[]> ChannelTypes { get; set; }

Expand All @@ -48,6 +54,8 @@ public ApplicationCommandOption(IApplicationCommandOption cmd)

Required = cmd.IsRequired ?? Optional<bool>.Unspecified;
Default = cmd.IsDefault ?? Optional<bool>.Unspecified;
MinValue = cmd.MinValue ?? Optional<double>.Unspecified;
MaxValue = cmd.MaxValue ?? Optional<double>.Unspecified;

Name = cmd.Name;
Type = cmd.Type;
Expand All @@ -66,6 +74,8 @@ public ApplicationCommandOption(ApplicationCommandOptionProperties option)
Required = option.Required ?? Optional<bool>.Unspecified;

Default = option.Default ?? Optional<bool>.Unspecified;
MinValue = option.MinValue ?? Optional<double>.Unspecified;
MaxValue = option.MaxValue ?? Optional<double>.Unspecified;

ChannelTypes = option.ChannelTypes?.ToArray() ?? Optional<ChannelType[]>.Unspecified;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ public class RestApplicationCommandOption : IApplicationCommandOption
/// <inheritdoc/>
public bool? IsRequired { get; private set; }

/// <inheritdoc/>
public double? MinValue { get; private set; }

/// <inheritdoc/>
public double? MaxValue { get; private set; }

/// <summary>
/// A collection of <see cref="RestApplicationCommandChoice"/>'s for this command.
/// </summary>
Expand All @@ -41,6 +47,7 @@ public class RestApplicationCommandOption : IApplicationCommandOption
/// </summary>
public IReadOnlyCollection<ChannelType> ChannelTypes { get; private set; }


internal RestApplicationCommandOption() { }

internal static RestApplicationCommandOption Create(Model model)
Expand All @@ -62,6 +69,12 @@ internal void Update(Model model)
if (model.Required.IsSpecified)
IsRequired = model.Required.Value;

if (model.MinValue.IsSpecified)
MinValue = model.MinValue.Value;

if (model.MaxValue.IsSpecified)
MaxValue = model.MaxValue.Value;

Options = model.Options.IsSpecified
? model.Options.Value.Select(Create).ToImmutableArray()
: ImmutableArray.Create<RestApplicationCommandOption>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public class SocketApplicationCommandOption : IApplicationCommandOption
/// <inheritdoc/>
public bool? IsRequired { get; private set; }

/// <inheritdoc/>
public double? MinValue { get; private set; }

/// <inheritdoc/>
public double? MaxValue { get; private set; }

/// <summary>
/// Choices for string and int types for the user to pick from.
/// </summary>
Expand Down Expand Up @@ -54,13 +60,13 @@ internal void Update(Model model)
Type = model.Type;
Description = model.Description;

IsDefault = model.Default.IsSpecified
? model.Default.Value
: null;
IsDefault = model.Default.ToNullable();

IsRequired = model.Required.ToNullable();

MinValue = model.MinValue.ToNullable();

IsRequired = model.Required.IsSpecified
? model.Required.Value
: null;
MaxValue = model.MaxValue.ToNullable();

Choices = model.Choices.IsSpecified
? model.Choices.Value.Select(SocketApplicationCommandChoice.Create).ToImmutableArray()
Expand Down

0 comments on commit 8e5e360

Please sign in to comment.