diff --git a/NetCord.Services/ApplicationCommands/SlashCommandIgnoreAttribute.cs b/NetCord.Services/ApplicationCommands/SlashCommandIgnoreAttribute.cs new file mode 100644 index 000000000..4339b9dcd --- /dev/null +++ b/NetCord.Services/ApplicationCommands/SlashCommandIgnoreAttribute.cs @@ -0,0 +1,10 @@ +namespace NetCord.Services.ApplicationCommands; + +/// +/// Specifies that an enum value should be ignored and not shown as an option in slash commands. +/// Apply this attribute to enum fields that should not be presented to users as choices. +/// +[AttributeUsage(AttributeTargets.Field)] +public class SlashCommandIgnoreAttribute : Attribute +{ +} diff --git a/NetCord.Services/EnumTypeReaders/SlashCommandEnumTypeReader.cs b/NetCord.Services/EnumTypeReaders/SlashCommandEnumTypeReader.cs index 082c14cbc..3880428ad 100644 --- a/NetCord.Services/EnumTypeReaders/SlashCommandEnumTypeReader.cs +++ b/NetCord.Services/EnumTypeReaders/SlashCommandEnumTypeReader.cs @@ -24,10 +24,11 @@ public bool TryRead(ReadOnlyMemory input, [MaybeNullWhen(false)] out objec { var localizationsProvider = parameter.LocalizationsProvider; - var count = fields.Length; + var filteredFields = fields.Where(f => f.GetCustomAttribute() is null).ToArray(); + var count = filteredFields.Length; var choices = new ApplicationCommandOptionChoiceProperties[count]; for (var i = 0; i < count; i++) - choices[i] = await CreateChoiceAsync(fields[i]).ConfigureAwait(false); + choices[i] = await CreateChoiceAsync(filteredFields[i]).ConfigureAwait(false); return choices; diff --git a/Tests/ServicesTest/ChoicesAndAutocompleteTests.cs b/Tests/ServicesTest/ChoicesAndAutocompleteTests.cs index 2ffdb0df0..b911e04aa 100644 --- a/Tests/ServicesTest/ChoicesAndAutocompleteTests.cs +++ b/Tests/ServicesTest/ChoicesAndAutocompleteTests.cs @@ -274,4 +274,39 @@ public void TestAutocompleteNotSupported() ([SlashCommandParameter(AutocompleteProviderType = typeof(TestAutocompleteProvider))] int i) => { })); }); } + + private enum TestEnumWithIgnoredValues + { + Value1, + [SlashCommandIgnore] + Value2, + Value3, + } + + [TestMethod] + public async Task TestEnumIgnoreAttribute() + { + var service = CreateService(); + + service.AddSlashCommand(new SlashCommandBuilder( + "test", + "Test", + (TestEnumWithIgnoredValues e) => { })); + + var command = (SlashCommandInfo)service.GetCommands().Single(); + + var parameter = command.Parameters.Single(); + + Assert.IsNotNull(parameter.ChoicesProvider); + + var choices = await parameter.ChoicesProvider.GetChoicesAsync(parameter).ConfigureAwait(false); + + Assert.IsNotNull(choices); + + var choicesList = choices.ToList(); + + Assert.AreEqual(2, choicesList.Count); + Assert.AreEqual("Value1", choicesList[0].Name); + Assert.AreEqual("Value3", choicesList[1].Name); + } }