diff --git a/interactions.go b/interactions.go index 4cb115be9..9a8687827 100644 --- a/interactions.go +++ b/interactions.go @@ -5,6 +5,7 @@ import ( "crypto/ed25519" "encoding/hex" "encoding/json" + "fmt" "io" "io/ioutil" "net/http" @@ -40,6 +41,30 @@ const ( ApplicationCommandOptionMentionable ApplicationCommandOptionType = 9 ) +func (t ApplicationCommandOptionType) String() string { + switch t { + case ApplicationCommandOptionSubCommand: + return "SubCommand" + case ApplicationCommandOptionSubCommandGroup: + return "SubCommandGroup" + case ApplicationCommandOptionString: + return "String" + case ApplicationCommandOptionInteger: + return "Integer" + case ApplicationCommandOptionBoolean: + return "Boolean" + case ApplicationCommandOptionUser: + return "User" + case ApplicationCommandOptionChannel: + return "Channel" + case ApplicationCommandOptionRole: + return "Role" + case ApplicationCommandOptionMentionable: + return "Mentionable" + } + return fmt.Sprintf("ApplicationCommandOptionType(%d)", t) +} + // ApplicationCommandOption represents an option/subcommand/subcommands group. type ApplicationCommandOption struct { Type ApplicationCommandOptionType `json:"type"` @@ -69,6 +94,18 @@ const ( InteractionMessageComponent InteractionType = 3 ) +func (t InteractionType) String() string { + switch t { + case InteractionPing: + return "Ping" + case InteractionApplicationCommand: + return "ApplicationCommand" + case InteractionMessageComponent: + return "MessageComponent" + } + return fmt.Sprintf("InteractionType(%d)", t) +} + // Interaction represents data of an interaction. type Interaction struct { ID string `json:"id"` @@ -135,12 +172,18 @@ func (i *Interaction) UnmarshalJSON(raw []byte) error { // MessageComponentData is helper function to assert the inner InteractionData to MessageComponentInteractionData. // Make sure to check that the Type of the interaction is InteractionMessageComponent before calling. func (i Interaction) MessageComponentData() (data MessageComponentInteractionData) { + if i.Type != InteractionMessageComponent { + panic("MessageComponentData called on interaction of type " + i.Type.String()) + } return i.Data.(MessageComponentInteractionData) } // ApplicationCommandData is helper function to assert the inner InteractionData to ApplicationCommandInteractionData. // Make sure to check that the Type of the interaction is InteractionApplicationCommand before calling. func (i Interaction) ApplicationCommandData() (data ApplicationCommandInteractionData) { + if i.Type != InteractionApplicationCommand { + panic("ApplicationCommandData called on interaction of type " + i.Type.String()) + } return i.Data.(ApplicationCommandInteractionData) } @@ -185,32 +228,32 @@ func (MessageComponentInteractionData) Type() InteractionType { // ApplicationCommandInteractionDataOption represents an option of a slash command. type ApplicationCommandInteractionDataOption struct { - Name string `json:"name"` - // NOTE: Contains the value specified by InteractionType. + Name string `json:"name"` + Type ApplicationCommandOptionType `json:"type"` + // NOTE: Contains the value specified by Type. Value interface{} `json:"value,omitempty"` Options []*ApplicationCommandInteractionDataOption `json:"options,omitempty"` } // IntValue is a utility function for casting option value to integer func (o ApplicationCommandInteractionDataOption) IntValue() int64 { - if v, ok := o.Value.(float64); ok { - return int64(v) + if o.Type != ApplicationCommandOptionInteger { + panic("IntValue called on data option of type " + o.Type.String()) } - - return 0 + return int64(o.Value.(float64)) } // UintValue is a utility function for casting option value to unsigned integer func (o ApplicationCommandInteractionDataOption) UintValue() uint64 { - if v, ok := o.Value.(float64); ok { - return uint64(v) + if o.Type != ApplicationCommandOptionInteger { + panic("UintValue called on data option of type " + o.Type.String()) } - - return 0 + return uint64(o.Value.(float64)) } // FloatValue is a utility function for casting option value to float func (o ApplicationCommandInteractionDataOption) FloatValue() float64 { + // TODO: limit calls to Number type once it is released if v, ok := o.Value.(float64); ok { return v } @@ -220,29 +263,27 @@ func (o ApplicationCommandInteractionDataOption) FloatValue() float64 { // StringValue is a utility function for casting option value to string func (o ApplicationCommandInteractionDataOption) StringValue() string { - if v, ok := o.Value.(string); ok { - return v + if o.Type != ApplicationCommandOptionString { + panic("StringValue called on data option of type " + o.Type.String()) } - - return "" + return o.Value.(string) } // BoolValue is a utility function for casting option value to bool func (o ApplicationCommandInteractionDataOption) BoolValue() bool { - if v, ok := o.Value.(bool); ok { - return v + if o.Type != ApplicationCommandOptionBoolean { + panic("BoolValue called on data option of type " + o.Type.String()) } - - return false + return o.Value.(bool) } // ChannelValue is a utility function for casting option value to channel object. // s : Session object, if not nil, function additionally fetches all channel's data func (o ApplicationCommandInteractionDataOption) ChannelValue(s *Session) *Channel { - chanID := o.StringValue() - if chanID == "" { - return nil + if o.Type != ApplicationCommandOptionChannel { + panic("ChannelValue called on data option of type " + o.Type.String()) } + chanID := o.Value.(string) if s == nil { return &Channel{ID: chanID} @@ -262,10 +303,10 @@ func (o ApplicationCommandInteractionDataOption) ChannelValue(s *Session) *Chann // RoleValue is a utility function for casting option value to role object. // s : Session object, if not nil, function additionally fetches all role's data func (o ApplicationCommandInteractionDataOption) RoleValue(s *Session, gID string) *Role { - roleID := o.StringValue() - if roleID == "" { - return nil + if o.Type != ApplicationCommandOptionRole && o.Type != ApplicationCommandOptionMentionable { + panic("RoleValue called on data option of type " + o.Type.String()) } + roleID := o.Value.(string) if s == nil || gID == "" { return &Role{ID: roleID} @@ -290,10 +331,10 @@ func (o ApplicationCommandInteractionDataOption) RoleValue(s *Session, gID strin // UserValue is a utility function for casting option value to user object. // s : Session object, if not nil, function additionally fetches all user's data func (o ApplicationCommandInteractionDataOption) UserValue(s *Session) *User { - userID := o.StringValue() - if userID == "" { - return nil + if o.Type != ApplicationCommandOptionUser && o.Type != ApplicationCommandOptionMentionable { + panic("UserValue called on data option of type " + o.Type.String()) } + userID := o.Value.(string) if s == nil { return &User{ID: userID}