From 8d78221de05c51169168d9e3fe548dceeb28aec5 Mon Sep 17 00:00:00 2001 From: diamondburned Date: Thu, 25 Nov 2021 15:02:24 -0800 Subject: [PATCH] discord: Improve union interface documentation; fix *Option JSON --- discord/command.go | 62 +++++++++++++++++++++++++++++ discord/component.go | 18 +++++++++ discord/interaction.go | 21 ++++++++-- utils/generate-option-marshalers.sh | 20 +++------- 4 files changed, 102 insertions(+), 19 deletions(-) diff --git a/discord/command.go b/discord/command.go index eeed870..82821f0 100644 --- a/discord/command.go +++ b/discord/command.go @@ -255,6 +255,20 @@ const ( // CommandOption is a union of command option types. The constructors for // CommandOption will hint the types that can be a CommandOption. +// +// The following types implement this interface: +// +// - *SubcommandGroupOption +// - *SubcommandOption +// - *StringOption +// - *IntegerOption +// - *BooleanOption +// - *UserOption +// - *ChannelOption +// - *RoleOption +// - *MentionableOption +// - *NumberOption +// type CommandOption interface { Name() string Type() CommandOptionType @@ -329,6 +343,18 @@ func (s *SubcommandOption) UnmarshalJSON(b []byte) error { } // CommandOptionValue is a subcommand option that fits into a subcommand. +// +// The following types implement this interface: +// +// - *StringOption +// - *IntegerOption +// - *BooleanOption +// - *UserOption +// - *ChannelOption +// - *RoleOption +// - *MentionableOption +// - *NumberOption +// type CommandOptionValue interface { CommandOption _val() @@ -641,3 +667,39 @@ func (u *UserOption) MarshalJSON() ([]byte, error) { raw: (*raw)(u), }) } + +// MarshalJSON marshals ChannelOption to JSON with the "type" field. +func (c *ChannelOption) MarshalJSON() ([]byte, error) { + type raw ChannelOption + return json.Marshal(struct { + Type CommandOptionType `json:"type"` + *raw + }{ + Type: c.Type(), + raw: (*raw)(c), + }) +} + +// MarshalJSON marshals RoleOption to JSON with the "type" field. +func (r *RoleOption) MarshalJSON() ([]byte, error) { + type raw RoleOption + return json.Marshal(struct { + Type CommandOptionType `json:"type"` + *raw + }{ + Type: r.Type(), + raw: (*raw)(r), + }) +} + +// MarshalJSON marshals MentionableOption to JSON with the "type" field. +func (m *MentionableOption) MarshalJSON() ([]byte, error) { + type raw MentionableOption + return json.Marshal(struct { + Type CommandOptionType `json:"type"` + *raw + }{ + Type: m.Type(), + raw: (*raw)(m), + }) +} diff --git a/discord/component.go b/discord/component.go index 3cf3177..3a00c36 100644 --- a/discord/component.go +++ b/discord/component.go @@ -64,6 +64,13 @@ func (c *ContainerComponents) UnmarshalJSON(b []byte) error { // Component is a component that can be attached to an interaction response. A // Component is either an InteractiveComponent or a ContainerComponent. See // those appropriate types for more information. +// +// The following types satisfy this interface: +// +// - *ActionRowComponent +// - *ButtonComponent +// - *SelectComponent +// type Component interface { // Type returns the type of the underlying component. Type() ComponentType @@ -73,6 +80,12 @@ type Component interface { // InteractiveComponent extends the Component for components that are // interactible, or components that aren't containers (like ActionRow). This is // useful for ActionRow to type-check that no nested ActionRows are allowed. +// +// The following types satisfy this interface: +// +// - *ButtonComponent +// - *SelectComponent +// type InteractiveComponent interface { Component // ID returns the ID of the underlying component. @@ -83,6 +96,11 @@ type InteractiveComponent interface { // ContainerComponent is the opposite of InteractiveComponent: it describes // components that only contain other components. The only component that // satisfies that is ActionRow. +// +// The following types satisfy this interface: +// +// - *ActionRowComponent +// type ContainerComponent interface { Component _ctn() diff --git a/discord/interaction.go b/discord/interaction.go index 0417e4f..c54deae 100644 --- a/discord/interaction.go +++ b/discord/interaction.go @@ -132,8 +132,16 @@ const ( // InteractionData holds the respose data of an interaction, or more // specifically, the data that Discord sends to us. Type assertions should be -// made on it to access the underlying data. The underlying types of the -// Responses are value types. See the constructors for the possible types. +// made on it to access the underlying data. +// +// The following types implement this interface: +// +// - *PingInteraction +// - *AutocompleteInteraction +// - *CommandInteraction +// - *SelectInteraction (also ComponentInteraction) +// - *ButtonInteraction (also ComponentInteraction) +// type InteractionData interface { InteractionType() InteractionDataType data() @@ -173,8 +181,13 @@ func (*AutocompleteInteraction) InteractionType() InteractionDataType { func (*AutocompleteInteraction) data() {} // ComponentInteraction is a union component interaction response types. The -// types can be whatever the constructors for this type will return. Underlying -// types of Response are all value types. +// types can be whatever the constructors for this type will return. +// +// The following types implement this interface: +// +// - *SelectInteraction +// - *ButtonInteraction +// type ComponentInteraction interface { InteractionData // ID returns the ID of the component in response. Not all component diff --git a/utils/generate-option-marshalers.sh b/utils/generate-option-marshalers.sh index 97166dc..06cfd54 100755 --- a/utils/generate-option-marshalers.sh +++ b/utils/generate-option-marshalers.sh @@ -12,29 +12,19 @@ types=( MentionableOption ) -recvs=( - s - s - s - i - b - u - c - r - m -) +for ((i = 0; i < ${#types[@]}; i++)); { + recv=$(head -c1 <<< "${types[$i]}" | tr "[:upper:]" "[:lower:]") -for ((i = 0; i < 6; i++)); { cat<