Skip to content

Commit 2f6d7c7

Browse files
committed
add instance value parsing to enum modalComponentConverter
1 parent 51e3239 commit 2f6d7c7

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

src/Discord.Net.Interactions/TypeConverters/ModalComponents/EnumModalComponentConverter.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ namespace Discord.Interactions;
99
internal sealed class EnumModalComponentConverter<T> : ModalComponentTypeConverter<T>
1010
where T : struct, Enum
1111
{
12+
private record Option(SelectMenuOptionBuilder OptionBuilder, Predicate<IDiscordInteraction> Predicate, T Value);
13+
1214
private readonly bool _isFlags;
13-
private readonly ImmutableArray<(SelectMenuOptionBuilder Option, Predicate<IDiscordInteraction> Predicate)> _options;
15+
private readonly ImmutableArray<Option> _options;
1416

1517
public EnumModalComponentConverter()
1618
{
1719
var names = Enum.GetNames(typeof(T));
1820
var members = names.SelectMany(x => typeof(T).GetMember(x));
1921

20-
_isFlags = typeof(T).GetCustomAttribute<FlagsAttribute>() is not null;
22+
_isFlags = typeof(T).IsDefined(typeof(FlagsAttribute));
2123

22-
_options = members.Select(x =>
24+
_options = members.Select<MemberInfo, Option>(x =>
2325
{
2426
var selectMenuOptionAttr = x.GetCustomAttribute<SelectMenuOptionAttribute>();
2527

@@ -29,10 +31,13 @@ public EnumModalComponentConverter()
2931
if (!string.IsNullOrEmpty(selectMenuOptionAttr?.Emote) && !(Emote.TryParse(selectMenuOptionAttr.Emote, out emote) || Emoji.TryParse(selectMenuOptionAttr.Emote, out emoji)))
3032
throw new ArgumentException($"Unable to parse {selectMenuOptionAttr.Emote} of {x.DeclaringType.Name}.{x.Name} into an {typeof(Emote).Name} or an {typeof(Emoji).Name}");
3133

32-
3334
var hideAttr = x.GetCustomAttribute<HideAttribute>();
3435
Predicate<IDiscordInteraction> predicate = hideAttr != null ? hideAttr.Predicate : null;
35-
return (new SelectMenuOptionBuilder(x.GetCustomAttribute<ChoiceDisplayAttribute>()?.Name ?? x.Name, x.Name, selectMenuOptionAttr?.Description, emote != null ? emote : emoji, selectMenuOptionAttr?.IsDefault), predicate);
36+
37+
var value = Enum.Parse<T>(x.Name);
38+
var optionBuilder = new SelectMenuOptionBuilder(x.GetCustomAttribute<ChoiceDisplayAttribute>()?.Name ?? x.Name, x.Name, selectMenuOptionAttr?.Description, emote != null ? emote : emoji, selectMenuOptionAttr?.IsDefault);
39+
40+
return new(optionBuilder, predicate, value);
3641
}).ToImmutableArray();
3742
}
3843

@@ -62,7 +67,17 @@ public override Task WriteAsync<TBuilder>(TBuilder builder, IDiscordInteraction
6267
if (selectMenu.MaxValues > 1 && !_isFlags)
6368
throw new InvalidOperationException($"Enum type {typeof(T).FullName} is not a [Flags] enum, so it cannot be used in a multi-select menu.");
6469

65-
selectMenu.WithOptions([.. _options.Where(x => !x.Predicate?.Invoke(interaction) ?? true).Select(x => x.Option)]);
70+
var visibleOptions = _options.Where(x => !x.Predicate?.Invoke(interaction) ?? true);
71+
72+
if (value is T enumValue)
73+
{
74+
foreach(var option in visibleOptions)
75+
{
76+
option.OptionBuilder.IsDefault = _isFlags ? enumValue.HasFlag(option.Value) : enumValue.Equals(option.Value);
77+
}
78+
}
79+
80+
selectMenu.WithOptions([.. visibleOptions.Select(x => x.OptionBuilder)]);
6681

6782
return Task.CompletedTask;
6883
}

0 commit comments

Comments
 (0)