RFC: Implement different select menus with a SelectMenuType
enum
#2217
Closed
archer-321
started this conversation in
Development & RFCs
Replies: 2 comments 5 replies
-
i dont think this is limited to select menus, but itd define how we handle whenever some fields exist based on the kind field |
Beta Was this translation helpful? Give feedback.
2 replies
-
With #2219 merged, I believe we can close this RFC. The PR linked above implemented the flattened approach for the reasons outlined in this comment. |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Sorry if I missed this project's preferred RFC format. I searched
CONTRIBUTING.md
and previous RFCs but couldn't find anything. Instead, I went for a template that mostly matches (some parts of) Rust's RFC template.Summary
Implement Discord's various select menu types (text, users, roles, mentionables, and channels) by moving type-specific data into a separate enum. This would move the
options
field into a new enum variant for text select menus, add adata
field to theSelectMenu
struct, and leave all other fields in the struct, as they apply to all kinds of select menus.Explanation
This RFC introduces a new enum:
SelectMenuData
with the variantsText
,User
,Role
,Mentionable
, andChannel
. This enum holds data specific to a single "type" of Discord select menu. Currently, this means it holds theoptions: Vec<SelectMenuOption>
field of text select menus (which would be moved out of SelectMenuData) andchannel_types: Option<Vec<ChannelType>>
of channel select menus. All other select menus get aSelectMenuData
variant without any fields.To specify the type of select menu to create, the developer constructs the
SelectMenu
instance with the respectiveSelectMenuData
variant. For variants without type-specific fields, this leads to the following code:Existing code simply moves the
options
field into an instance ofSelectMenuData::Text
:Drawbacks
Especially when new to the library, users might look for a
type
(kind
) field to "select" the type of select menu they're creating. With this design, they'll have to use thedata
field instead.Moreover, users might look for individual structures like
TextSelectMenu
instead of a "partially flattened"SelectMenu
considering the various select menu types have differenttype
IDs (just like buttons have a differenttype
ID).Rationale and alternatives
The "partially flattened" approach outlined above combines the advantages of a single "flattened" structure with those of individual structures for the various select menu types:
custom_id
,placeholder
,min_values
,max_values
, anddisabled
) don't get duplicated for every select menu type.options
if they're implementing a user select menu).options
to contain a list of possible role IDs for role select menus), this doesn't require a breaking change to Twilight's API. Instead, the affected enum variant can contain the new field without affecting other variants already containing a field with the same name.Alternative implementations include:
Option
). This has the advantage that no fields are duplicated, but it's possible to (try to) access fields unrelated to the current kind of select menu. Moreover, this would require atype
(kind
) field to differentiate some types of select menus that have the same set of fields (e.g. user and role select menus). Finally, this doesn't provide the third advantage listed above (colliding fields with different data types) without requiring an even more customized (de-)serialization.Prior art
Pull Request #2051 implements the separate struct approach mentioned above. Moreover, a review comment on this PR discusses the other possible implementations and their advantages. This comment also lists the
Channel
andInteraction
types that were flattened for different reasons.Finally, the current state of select menus is described in Discord's API docs.
Unresolved questions
As this RFC essentially makes
data
the main field that defines the select menu's type, the namekind
ormenu_type
might be more appropriate. However, users might not expect this field to hold type-specific data, then.Considering most data enum variants don't have any fields at all, it might be worth boxing the variants that have. Even though they currently only hold one field each, boxing them for future updates would be breaking change (for code that doesn't have to construct the variant's fields). However, this would require creating new structs for the individual variants.
The PR linked above implements the different select menu types in individual modules. Considering that the select menu module isn't particularly long, it might be more convenient to implement those types in the
select_menu
module directly instead of creating a new module andpub use
for every new upstream type.Beta Was this translation helpful? Give feedback.
All reactions