From d290b0d01c8aac223ef06e423502b79d432e2471 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Tue, 21 Jul 2020 14:27:59 -0600 Subject: [PATCH] *: Add typed Snowflake IDs (#122) This PR closes #120. --- api/channel.go | 35 +++-- api/emoji.go | 17 ++- api/guild.go | 66 +++++----- api/integration_test.go | 4 +- api/invite.go | 6 +- api/member.go | 40 +++--- api/message.go | 38 +++--- api/message_reaction.go | 22 ++-- api/role.go | 17 ++- api/send.go | 8 +- api/send_test.go | 14 +- api/user.go | 14 +- api/webhook.go | 20 +-- bot/extras/arguments/emoji.go | 4 +- bot/extras/arguments/link.go | 12 +- bot/extras/arguments/mention.go | 6 +- bot/extras/infer/infer.go | 12 +- bot/extras/infer/infer_test.go | 4 +- bot/extras/middlewares/middlewares_test.go | 16 +-- discord/auditlog.go | 26 ++-- discord/channel.go | 12 +- discord/emoji.go | 10 +- discord/guild.go | 34 ++--- discord/message.go | 38 +++--- discord/permission.go | 8 +- discord/snowflake.go | 137 ++++++++++++++++++++ discord/user.go | 24 ++-- discord/voice.go | 6 +- discord/webhook.go | 6 +- gateway/commands.go | 16 +-- gateway/events.go | 142 ++++++++++----------- gateway/ready.go | 28 ++-- state/state.go | 56 ++++---- state/state_events.go | 2 +- state/store.go | 54 ++++---- state/store_default.go | 82 ++++++------ state/store_noop.go | 54 ++++---- utils/moreatomic/guildid_set.go | 51 ++++++++ voice/integration_test.go | 4 +- voice/session.go | 13 +- voice/voice.go | 14 +- voice/voicegateway/commands.go | 14 +- voice/voicegateway/gateway.go | 6 +- 43 files changed, 687 insertions(+), 505 deletions(-) create mode 100644 utils/moreatomic/guildid_set.go diff --git a/api/channel.go b/api/channel.go index c41a640..2a77d39 100644 --- a/api/channel.go +++ b/api/channel.go @@ -9,7 +9,7 @@ import ( var EndpointChannels = Endpoint + "channels/" // Channels returns a list of guild channel objects. -func (c *Client) Channels(guildID discord.Snowflake) ([]discord.Channel, error) { +func (c *Client) Channels(guildID discord.GuildID) ([]discord.Channel, error) { var chs []discord.Channel return chs, c.RequestJSON(&chs, "GET", EndpointGuilds+guildID.String()+"/channels") } @@ -56,7 +56,7 @@ type CreateChannelData struct { // CategoryID is the id of the parent category for a channel. // // Channel Types: Text, News, Store, Voice - CategoryID discord.Snowflake `json:"parent_id,string,omitempty"` + CategoryID discord.ChannelID `json:"parent_id,string,omitempty"` // NSFW specifies whether the channel is nsfw. // // Channel Types: Text, News, Store. @@ -68,7 +68,7 @@ type CreateChannelData struct { // Requires the MANAGE_CHANNELS permission. // Fires a Channel Create Gateway event. func (c *Client) CreateChannel( - guildID discord.Snowflake, data CreateChannelData) (*discord.Channel, error) { + guildID discord.GuildID, data CreateChannelData) (*discord.Channel, error) { var ch *discord.Channel return ch, c.RequestJSON( &ch, "POST", @@ -79,7 +79,7 @@ func (c *Client) CreateChannel( type MoveChannelData struct { // ID is the channel id. - ID discord.Snowflake `json:"id"` + ID discord.ChannelID `json:"id"` // Position is the sorting position of the channel Position option.Int `json:"position"` } @@ -87,7 +87,7 @@ type MoveChannelData struct { // MoveChannel modifies the position of channels in the guild. // // Requires MANAGE_CHANNELS. -func (c *Client) MoveChannel(guildID discord.Snowflake, datum []MoveChannelData) error { +func (c *Client) MoveChannel(guildID discord.GuildID, datum []MoveChannelData) error { return c.FastRequest( "PATCH", EndpointGuilds+guildID.String()+"/channels", httputil.WithJSONBody(datum), @@ -95,7 +95,7 @@ func (c *Client) MoveChannel(guildID discord.Snowflake, datum []MoveChannelData) } // Channel gets a channel by ID. Returns a channel object. -func (c *Client) Channel(channelID discord.Snowflake) (*discord.Channel, error) { +func (c *Client) Channel(channelID discord.ChannelID) (*discord.Channel, error) { var channel *discord.Channel return channel, c.RequestJSON(&channel, "GET", EndpointChannels+channelID.String()) } @@ -147,13 +147,13 @@ type ModifyChannelData struct { Permissions *[]discord.Overwrite `json:"permission_overwrites,omitempty"` // CategoryID is the id of the new parent category for a channel. // Channel Types: Text, News, Store, Voice - CategoryID discord.Snowflake `json:"parent_id,string,omitempty"` + CategoryID discord.ChannelID `json:"parent_id,string,omitempty"` } // ModifyChannel updates a channel's settings. // // Requires the MANAGE_CHANNELS permission for the guild. -func (c *Client) ModifyChannel(channelID discord.Snowflake, data ModifyChannelData) error { +func (c *Client) ModifyChannel(channelID discord.ChannelID, data ModifyChannelData) error { return c.FastRequest("PATCH", EndpointChannels+channelID.String(), httputil.WithJSONBody(data)) } @@ -163,7 +163,7 @@ func (c *Client) ModifyChannel(channelID discord.Snowflake, data ModifyChannelDa // Channel Update Gateway event will fire for each of them. // // Fires a Channel Delete Gateway event. -func (c *Client) DeleteChannel(channelID discord.Snowflake) error { +func (c *Client) DeleteChannel(channelID discord.ChannelID) error { return c.FastRequest("DELETE", EndpointChannels+channelID.String()) } @@ -181,7 +181,7 @@ type EditChannelPermissionData struct { // // Requires the MANAGE_ROLES permission. func (c *Client) EditChannelPermission( - channelID, overwriteID discord.Snowflake, data EditChannelPermissionData) error { + channelID discord.ChannelID, overwriteID discord.Snowflake, data EditChannelPermissionData) error { return c.FastRequest( "PUT", EndpointChannels+channelID.String()+"/permissions/"+overwriteID.String(), @@ -202,13 +202,13 @@ func (c *Client) DeleteChannelPermission(channelID, overwriteID discord.Snowflak // Typing posts a typing indicator to the channel. Undocumented, but the client // usually clears the typing indicator after 8-10 seconds (or after a message). -func (c *Client) Typing(channelID discord.Snowflake) error { +func (c *Client) Typing(channelID discord.ChannelID) error { return c.FastRequest("POST", EndpointChannels+channelID.String()+"/typing") } // PinnedMessages returns all pinned messages in the channel as an array of // message objects. -func (c *Client) PinnedMessages(channelID discord.Snowflake) ([]discord.Message, error) { +func (c *Client) PinnedMessages(channelID discord.ChannelID) ([]discord.Message, error) { var pinned []discord.Message return pinned, c.RequestJSON(&pinned, "GET", EndpointChannels+channelID.String()+"/pins") } @@ -216,22 +216,21 @@ func (c *Client) PinnedMessages(channelID discord.Snowflake) ([]discord.Message, // PinMessage pins a message in a channel. // // Requires the MANAGE_MESSAGES permission. -func (c *Client) PinMessage(channelID, messageID discord.Snowflake) error { +func (c *Client) PinMessage(channelID discord.ChannelID, messageID discord.MessageID) error { return c.FastRequest("PUT", EndpointChannels+channelID.String()+"/pins/"+messageID.String()) } // UnpinMessage deletes a pinned message in a channel. // // Requires the MANAGE_MESSAGES permission. -func (c *Client) UnpinMessage(channelID, messageID discord.Snowflake) error { +func (c *Client) UnpinMessage(channelID discord.ChannelID, messageID discord.MessageID) error { return c.FastRequest("DELETE", EndpointChannels+channelID.String()+"/pins/"+messageID.String()) } // AddRecipient adds a user to a group direct message. As accessToken is needed, // clearly this endpoint should only be used for OAuth. AccessToken can be // obtained with the "gdm.join" scope. -func (c *Client) AddRecipient( - channelID, userID discord.Snowflake, accessToken, nickname string) error { +func (c *Client) AddRecipient(channelID discord.ChannelID, userID discord.UserID, accessToken, nickname string) error { var params struct { AccessToken string `json:"access_token"` @@ -249,7 +248,7 @@ func (c *Client) AddRecipient( } // RemoveRecipient removes a user from a group direct message. -func (c *Client) RemoveRecipient(channelID, userID discord.Snowflake) error { +func (c *Client) RemoveRecipient(channelID discord.ChannelID, userID discord.UserID) error { return c.FastRequest( "DELETE", EndpointChannels+channelID.String()+"/recipients/"+userID.String(), @@ -264,7 +263,7 @@ type Ack struct { // Ack marks the read state of a channel. This is undocumented. The method will // write to the ack variable passed in. If this method is called asynchronously, // then ack should be mutex guarded. -func (c *Client) Ack(channelID, messageID discord.Snowflake, ack *Ack) error { +func (c *Client) Ack(channelID discord.ChannelID, messageID discord.MessageID, ack *Ack) error { return c.RequestJSON( ack, "POST", EndpointChannels+channelID.String()+"/messages/"+messageID.String()+"/ack", diff --git a/api/emoji.go b/api/emoji.go index a8606b6..0ddac5b 100644 --- a/api/emoji.go +++ b/api/emoji.go @@ -12,18 +12,18 @@ type Emoji = string // NewCustomEmoji creates a new Emoji using a custom guild emoji as // base. // Unicode emojis should be directly passed to the function using Emoji. -func NewCustomEmoji(id discord.Snowflake, name string) Emoji { +func NewCustomEmoji(id discord.EmojiID, name string) Emoji { return name + ":" + id.String() } // Emojis returns a list of emoji objects for the given guild. -func (c *Client) Emojis(guildID discord.Snowflake) ([]discord.Emoji, error) { +func (c *Client) Emojis(guildID discord.GuildID) ([]discord.Emoji, error) { var emjs []discord.Emoji return emjs, c.RequestJSON(&emjs, "GET", EndpointGuilds+guildID.String()+"/emojis") } // Emoji returns an emoji object for the given guild and emoji IDs. -func (c *Client) Emoji(guildID, emojiID discord.Snowflake) (*discord.Emoji, error) { +func (c *Client) Emoji(guildID discord.GuildID, emojiID discord.EmojiID) (*discord.Emoji, error) { var emj *discord.Emoji return emj, c.RequestJSON(&emj, "GET", EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String()) @@ -36,7 +36,7 @@ type CreateEmojiData struct { // Image is the the 128x128 emoji image. Image Image `json:"image"` // Roles are the roles for which this emoji will be whitelisted. - Roles *[]discord.Snowflake `json:"roles,omitempty"` + Roles *[]discord.RoleID `json:"roles,omitempty"` } // CreateEmoji creates a new emoji in the guild. This endpoint requires @@ -44,8 +44,7 @@ type CreateEmojiData struct { // "image/gif". However, ContentType can also be automatically detected // (though shouldn't be relied on). // Emojis and animated emojis have a maximum file size of 256kb. -func (c *Client) CreateEmoji( - guildID discord.Snowflake, data CreateEmojiData) (*discord.Emoji, error) { +func (c *Client) CreateEmoji(guildID discord.GuildID, data CreateEmojiData) (*discord.Emoji, error) { // Max 256KB if err := data.Image.Validate(256 * 1000); err != nil { @@ -65,14 +64,14 @@ type ModifyEmojiData struct { // Name is the name of the emoji. Name string `json:"name,omitempty"` // Roles are the roles to which this emoji will be whitelisted. - Roles *[]discord.Snowflake `json:"roles,omitempty"` + Roles *[]discord.RoleID `json:"roles,omitempty"` } // ModifyEmoji changes an existing emoji. This requires MANAGE_EMOJIS. Name and // roles are optional fields (though you'd want to change either though). // // Fires a Guild Emojis Update Gateway event. -func (c *Client) ModifyEmoji(guildID, emojiID discord.Snowflake, data ModifyEmojiData) error { +func (c *Client) ModifyEmoji(guildID discord.GuildID, emojiID discord.EmojiID, data ModifyEmojiData) error { return c.FastRequest( "PATCH", EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String(), @@ -84,6 +83,6 @@ func (c *Client) ModifyEmoji(guildID, emojiID discord.Snowflake, data ModifyEmoj // // Requires the MANAGE_EMOJIS permission. // Fires a Guild Emojis Update Gateway event. -func (c *Client) DeleteEmoji(guildID, emojiID discord.Snowflake) error { +func (c *Client) DeleteEmoji(guildID discord.GuildID, emojiID discord.EmojiID) error { return c.FastRequest("DELETE", EndpointGuilds+guildID.String()+"/emojis/"+emojiID.String()) } diff --git a/api/guild.go b/api/guild.go index c6d1bcf..f61f2eb 100644 --- a/api/guild.go +++ b/api/guild.go @@ -55,13 +55,13 @@ type CreateGuildData struct { Channels []discord.Channel `json:"channels,omitempty"` // AFKChannelID is the id for the afk channel. - AFKChannelID discord.Snowflake `json:"afk_channel_id,omitempty"` + AFKChannelID discord.ChannelID `json:"afk_channel_id,omitempty"` // AFKTimeout is the afk timeout in seconds. AFKTimeout option.Seconds `json:"afk_timeout,omitempty"` // SystemChannelID is the id of the channel where guild notices such as // welcome messages and boost events are posted. - SystemChannelID discord.Snowflake `json:"system_channel_id,omitempty"` + SystemChannelID discord.ChannelID `json:"system_channel_id,omitempty"` } // CreateGuild creates a new guild. Returns a guild object on success. @@ -75,7 +75,7 @@ func (c *Client) CreateGuild(data CreateGuildData) (*discord.Guild, error) { // Guild returns the guild object for the given id. // ApproximateMembers and ApproximatePresences will not be set. -func (c *Client) Guild(id discord.Snowflake) (*discord.Guild, error) { +func (c *Client) Guild(id discord.GuildID) (*discord.Guild, error) { var g *discord.Guild return g, c.RequestJSON(&g, "GET", EndpointGuilds+id.String()) } @@ -84,7 +84,7 @@ func (c *Client) Guild(id discord.Snowflake) (*discord.Guild, error) { // user is not in the guild. // // This endpoint is only for public guilds. -func (c *Client) GuildPreview(id discord.Snowflake) (*discord.GuildPreview, error) { +func (c *Client) GuildPreview(id discord.GuildID) (*discord.GuildPreview, error) { var g *discord.GuildPreview return g, c.RequestJSON(&g, "GET", EndpointGuilds+id.String()+"/preview") } @@ -92,7 +92,7 @@ func (c *Client) GuildPreview(id discord.Snowflake) (*discord.GuildPreview, erro // GuildWithCount returns the guild object for the given id. // This will also set the ApproximateMembers and ApproximatePresences fields // of the guild struct. -func (c *Client) GuildWithCount(id discord.Snowflake) (*discord.Guild, error) { +func (c *Client) GuildWithCount(id discord.GuildID) (*discord.Guild, error) { var g *discord.Guild return g, c.RequestJSON( &g, "GET", @@ -133,7 +133,7 @@ func (c *Client) Guilds(limit uint) ([]discord.Guild, error) { // may be less, if no more guilds are available. // // Requires the guilds OAuth2 scope. -func (c *Client) GuildsBefore(before discord.Snowflake, limit uint) ([]discord.Guild, error) { +func (c *Client) GuildsBefore(before discord.GuildID, limit uint) ([]discord.Guild, error) { var guilds []discord.Guild // this is the limit of max guilds per request,as imposed by Discord @@ -175,7 +175,7 @@ func (c *Client) GuildsBefore(before discord.Snowflake, limit uint) ([]discord.G // may be less, if no more guilds are available. // // Requires the guilds OAuth2 scope. -func (c *Client) GuildsAfter(after discord.Snowflake, limit uint) ([]discord.Guild, error) { +func (c *Client) GuildsAfter(after discord.GuildID, limit uint) ([]discord.Guild, error) { var guilds []discord.Guild // this is the limit of max guilds per request, as imposed by Discord @@ -208,11 +208,11 @@ func (c *Client) GuildsAfter(after discord.Snowflake, limit uint) ([]discord.Gui } func (c *Client) guildsRange( - before, after discord.Snowflake, limit uint) ([]discord.Guild, error) { + before, after discord.GuildID, limit uint) ([]discord.Guild, error) { var param struct { - Before discord.Snowflake `schema:"before,omitempty"` - After discord.Snowflake `schema:"after,omitempty"` + Before discord.GuildID `schema:"before,omitempty"` + After discord.GuildID `schema:"after,omitempty"` Limit uint `schema:"limit"` } @@ -230,7 +230,7 @@ func (c *Client) guildsRange( } // LeaveGuild leaves a guild. -func (c *Client) LeaveGuild(id discord.Snowflake) error { +func (c *Client) LeaveGuild(id discord.GuildID) error { return c.FastRequest("DELETE", EndpointMe+"/guilds/"+id.String()) } @@ -257,7 +257,7 @@ type ModifyGuildData struct { // AFKChannelID is the id for the afk channel. // // This field is nullable. - AFKChannelID discord.Snowflake `json:"afk_channel_id,string,omitempty"` + AFKChannelID discord.ChannelID `json:"afk_channel_id,string,omitempty"` // AFKTimeout is the afk timeout in seconds. AFKTimeout option.Seconds `json:"afk_timeout,omitempty"` // Icon is the base64 1024x1024 png/jpeg/gif image for the guild icon @@ -271,23 +271,23 @@ type ModifyGuildData struct { Banner *Image `json:"banner,omitempty"` // OwnerID is the user id to transfer guild ownership to (must be owner). - OwnerID discord.Snowflake `json:"owner_id,omitempty"` + OwnerID discord.UserID `json:"owner_id,omitempty"` // SystemChannelID is the id of the channel where guild notices such as // welcome messages and boost events are posted. // // This field is nullable. - SystemChannelID discord.Snowflake `json:"system_channel_id,omitempty"` + SystemChannelID discord.ChannelID `json:"system_channel_id,omitempty"` // RulesChannelID is the id of the channel where "PUBLIC" guilds display // rules and/or guidelines. // // This field is nullable. - RulesChannelID discord.Snowflake `json:"rules_channel_id,omitempty"` + RulesChannelID discord.ChannelID `json:"rules_channel_id,omitempty"` // PublicUpdatesChannelID is the id of the channel where admins and // moderators of "PUBLIC" guilds receive notices from Discord. // // This field is nullable. - PublicUpdatesChannelID discord.Snowflake `json:"public_updates_channel_id,omitempty"` + PublicUpdatesChannelID discord.ChannelID `json:"public_updates_channel_id,omitempty"` // PreferredLocale is the preferred locale of a "PUBLIC" guild used in // server discovery and notices from Discord. @@ -298,7 +298,7 @@ type ModifyGuildData struct { // ModifyGuild modifies a guild's settings. Requires the MANAGE_GUILD permission. // Fires a Guild Update Gateway event. -func (c *Client) ModifyGuild(id discord.Snowflake, data ModifyGuildData) (*discord.Guild, error) { +func (c *Client) ModifyGuild(id discord.GuildID, data ModifyGuildData) (*discord.Guild, error) { var g *discord.Guild return g, c.RequestJSON( &g, "PATCH", @@ -311,13 +311,13 @@ func (c *Client) ModifyGuild(id discord.Snowflake, data ModifyGuildData) (*disco // DeleteGuild deletes a guild permanently. The User must be owner. // // Fires a Guild Delete Gateway event. -func (c *Client) DeleteGuild(id discord.Snowflake) error { +func (c *Client) DeleteGuild(id discord.GuildID) error { return c.FastRequest("DELETE", EndpointGuilds+id.String()) } // GuildVoiceRegions is the same as /voice, but returns VIP ones as well if // available. -func (c *Client) VoiceRegionsGuild(guildID discord.Snowflake) ([]discord.VoiceRegion, error) { +func (c *Client) VoiceRegionsGuild(guildID discord.GuildID) ([]discord.VoiceRegion, error) { var vrs []discord.VoiceRegion return vrs, c.RequestJSON(&vrs, "GET", EndpointGuilds+guildID.String()+"/regions") } @@ -325,7 +325,7 @@ func (c *Client) VoiceRegionsGuild(guildID discord.Snowflake) ([]discord.VoiceRe // https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log-query-string-parameters type AuditLogData struct { // UserID filters the log for actions made by a user. - UserID discord.Snowflake `schema:"user_id,omitempty"` + UserID discord.UserID `schema:"user_id,omitempty"` // ActionType is the type of audit log event. ActionType discord.AuditLogEvent `schema:"action_type,omitempty"` // Before filters the log before a certain entry ID. @@ -338,7 +338,7 @@ type AuditLogData struct { // AuditLog returns an audit log object for the guild. // // Requires the VIEW_AUDIT_LOG permission. -func (c *Client) AuditLog(guildID discord.Snowflake, data AuditLogData) (*discord.AuditLog, error) { +func (c *Client) AuditLog(guildID discord.GuildID, data AuditLogData) (*discord.AuditLog, error) { switch { case data.Limit == 0: data.Limit = 50 @@ -358,7 +358,7 @@ func (c *Client) AuditLog(guildID discord.Snowflake, data AuditLogData) (*discor // Integrations returns a list of integration objects for the guild. // // Requires the MANAGE_GUILD permission. -func (c *Client) Integrations(guildID discord.Snowflake) ([]discord.Integration, error) { +func (c *Client) Integrations(guildID discord.GuildID) ([]discord.Integration, error) { var ints []discord.Integration return ints, c.RequestJSON(&ints, "GET", EndpointGuilds+guildID.String()+"/integrations") } @@ -369,11 +369,11 @@ func (c *Client) Integrations(guildID discord.Snowflake) ([]discord.Integration, // Requires the MANAGE_GUILD permission. // Fires a Guild Integrations Update Gateway event. func (c *Client) AttachIntegration(guildID, - integrationID discord.Snowflake, integrationType discord.Service) error { + integrationID discord.IntegrationID, integrationType discord.Service) error { var param struct { - Type discord.Service `json:"type"` - ID discord.Snowflake `json:"id"` + Type discord.Service `json:"type"` + ID discord.IntegrationID `json:"id"` } param.Type = integrationType @@ -405,7 +405,7 @@ type ModifyIntegrationData struct { // Requires the MANAGE_GUILD permission. // Fires a Guild Integrations Update Gateway event. func (c *Client) ModifyIntegration( - guildID, integrationID discord.Snowflake, data ModifyIntegrationData) error { + guildID discord.GuildID, integrationID discord.IntegrationID, data ModifyIntegrationData) error { return c.FastRequest( "PATCH", EndpointGuilds+guildID.String()+"/integrations/"+integrationID.String(), @@ -414,7 +414,7 @@ func (c *Client) ModifyIntegration( } // Sync an integration. Requires the MANAGE_GUILD permission. -func (c *Client) SyncIntegration(guildID, integrationID discord.Snowflake) error { +func (c *Client) SyncIntegration(guildID discord.GuildID, integrationID discord.IntegrationID) error { return c.FastRequest( "POST", EndpointGuilds+guildID.String()+"/integrations/"+integrationID.String()+"/sync", @@ -424,7 +424,7 @@ func (c *Client) SyncIntegration(guildID, integrationID discord.Snowflake) error // GuildWidget returns the guild widget object. // // Requires the MANAGE_GUILD permission. -func (c *Client) GuildWidget(guildID discord.Snowflake) (*discord.GuildWidget, error) { +func (c *Client) GuildWidget(guildID discord.GuildID) (*discord.GuildWidget, error) { var ge *discord.GuildWidget return ge, c.RequestJSON(&ge, "GET", EndpointGuilds+guildID.String()+"/widget") } @@ -434,14 +434,14 @@ type ModifyGuildWidgetData struct { // Enabled specifies whether the widget is enabled. Enabled option.Bool `json:"enabled,omitempty"` // ChannelID is the widget channel id. - ChannelID discord.Snowflake `json:"channel_id,omitempty"` + ChannelID discord.ChannelID `json:"channel_id,omitempty"` } // ModifyGuildWidget modifies a guild widget object for the guild. // // Requires the MANAGE_GUILD permission. func (c *Client) ModifyGuildWidget( - guildID discord.Snowflake, data ModifyGuildWidgetData) (*discord.GuildWidget, error) { + guildID discord.GuildID, data ModifyGuildWidgetData) (*discord.GuildWidget, error) { var w *discord.GuildWidget return w, c.RequestJSON( @@ -456,7 +456,7 @@ func (c *Client) ModifyGuildWidget( // guild is not set. // // Requires MANAGE_GUILD. -func (c *Client) GuildVanityURL(guildID discord.Snowflake) (*discord.Invite, error) { +func (c *Client) GuildVanityURL(guildID discord.GuildID) (*discord.Invite, error) { var inv *discord.Invite return inv, c.RequestJSON(&inv, "GET", EndpointGuilds+guildID.String()+"/vanity-url") } @@ -496,13 +496,13 @@ const ( // GuildImageURL returns a link to the PNG image widget for the guild. // // Requires no permissions or authentication. -func (c *Client) GuildImageURL(guildID discord.Snowflake, img GuildImageStyle) string { +func (c *Client) GuildImageURL(guildID discord.GuildID, img GuildImageStyle) string { return EndpointGuilds + guildID.String() + "/widget.png?style=" + string(img) } // GuildImage returns a PNG image widget for the guild. Requires no permissions // or authentication. -func (c *Client) GuildImage(guildID discord.Snowflake, img GuildImageStyle) (io.ReadCloser, error) { +func (c *Client) GuildImage(guildID discord.GuildID, img GuildImageStyle) (io.ReadCloser, error) { r, err := c.Request("GET", c.GuildImageURL(guildID, img)) if err != nil { return nil, err diff --git a/api/integration_test.go b/api/integration_test.go index 5301e20..b0ae4f2 100644 --- a/api/integration_test.go +++ b/api/integration_test.go @@ -14,7 +14,7 @@ import ( type testConfig struct { BotToken string - ChannelID discord.Snowflake + ChannelID discord.ChannelID } func mustConfig(t *testing.T) testConfig { @@ -35,7 +35,7 @@ func mustConfig(t *testing.T) testConfig { return testConfig{ BotToken: token, - ChannelID: id, + ChannelID: discord.ChannelID(id), } } diff --git a/api/invite.go b/api/invite.go index 81124d6..455aca2 100644 --- a/api/invite.go +++ b/api/invite.go @@ -39,7 +39,7 @@ func (c *Client) InviteWithCounts(code string) (*discord.Invite, error) { // the channel. Only usable for guild channels. // // Requires the MANAGE_CHANNELS permission. -func (c *Client) ChannelInvites(channelID discord.Snowflake) ([]discord.Invite, error) { +func (c *Client) ChannelInvites(channelID discord.ChannelID) ([]discord.Invite, error) { var invs []discord.Invite return invs, c.RequestJSON(&invs, "GET", EndpointChannels+channelID.String()+"/invites") @@ -49,7 +49,7 @@ func (c *Client) ChannelInvites(channelID discord.Snowflake) ([]discord.Invite, // guild. // // Requires the MANAGE_GUILD permission. -func (c *Client) GuildInvites(guildID discord.Snowflake) ([]discord.Invite, error) { +func (c *Client) GuildInvites(guildID discord.GuildID) ([]discord.Invite, error) { var invs []discord.Invite return invs, c.RequestJSON(&invs, "GET", EndpointGuilds+guildID.String()+"/invites") @@ -82,7 +82,7 @@ type CreateInviteData struct { // // Requires the CREATE_INSTANT_INVITE permission. func (c *Client) CreateInvite( - channelID discord.Snowflake, data CreateInviteData) (*discord.Invite, error) { + channelID discord.ChannelID, data CreateInviteData) (*discord.Invite, error) { var inv *discord.Invite return inv, c.RequestJSON( &inv, "POST", diff --git a/api/member.go b/api/member.go index 320078c..e9e15ba 100644 --- a/api/member.go +++ b/api/member.go @@ -7,7 +7,7 @@ import ( ) // Member returns a guild member object for the specified user.. -func (c *Client) Member(guildID, userID discord.Snowflake) (*discord.Member, error) { +func (c *Client) Member(guildID discord.GuildID, userID discord.UserID) (*discord.Member, error) { var m *discord.Member return m, c.RequestJSON(&m, "GET", EndpointGuilds+guildID.String()+"/members/"+userID.String()) } @@ -21,7 +21,7 @@ func (c *Client) Member(guildID, userID discord.Snowflake) (*discord.Member, err // they may be less, if no more members are available. // // When fetching the members, those with the smallest ID will be fetched first. -func (c *Client) Members(guildID discord.Snowflake, limit uint) ([]discord.Member, error) { +func (c *Client) Members(guildID discord.GuildID, limit uint) ([]discord.Member, error) { return c.MembersAfter(guildID, 0, limit) } @@ -33,7 +33,7 @@ func (c *Client) Members(guildID discord.Snowflake, limit uint) ([]discord.Membe // maximum a total of limit/1000 rounded up requests will be made, although // they may be less, if no more members are available. func (c *Client) MembersAfter( - guildID, after discord.Snowflake, limit uint) ([]discord.Member, error) { + guildID discord.GuildID, after discord.UserID, limit uint) ([]discord.Member, error) { var mems []discord.Member @@ -67,7 +67,7 @@ func (c *Client) MembersAfter( } func (c *Client) membersAfter( - guildID, after discord.Snowflake, limit uint) ([]discord.Member, error) { + guildID discord.GuildID, after discord.UserID, limit uint) ([]discord.Member, error) { switch { case limit == 0: @@ -77,8 +77,8 @@ func (c *Client) membersAfter( } var param struct { - After discord.Snowflake `schema:"after,omitempty"` - Limit uint `schema:"limit"` + After discord.UserID `schema:"after,omitempty"` + Limit uint `schema:"limit"` } param.Limit = limit @@ -104,7 +104,7 @@ type AddMemberData struct { // Roles is an array of role ids the member is assigned. // // Requires MANAGE_ROLES. - Roles *[]discord.Snowflake `json:"roles,omitempty"` + Roles *[]discord.RoleID `json:"roles,omitempty"` // Mute specifies whether the user is muted in voice channels. // // Requires MUTE_MEMBERS. @@ -126,7 +126,7 @@ type AddMemberData struct { // application used for authorization), and the bot must be a member of the // guild with CREATE_INSTANT_INVITE permission. func (c *Client) AddMember( - guildID, userID discord.Snowflake, data AddMemberData) (*discord.Member, error) { + guildID discord.GuildID, userID discord.UserID, data AddMemberData) (*discord.Member, error) { var mem *discord.Member return mem, c.RequestJSON( &mem, "PUT", @@ -144,7 +144,7 @@ type ModifyMemberData struct { // Roles is an array of role ids the member is assigned. // // Requires MANAGE_ROLES. - Roles *[]discord.Snowflake `json:"roles,omitempty"` + Roles *[]discord.RoleID `json:"roles,omitempty"` // Mute specifies whether the user is muted in voice channels. // // Requires MUTE_MEMBERS. @@ -158,14 +158,14 @@ type ModifyMemberData struct { // connected to voice). // // Requires MOVE_MEMBER - VoiceChannel discord.Snowflake `json:"channel_id,omitempty"` + VoiceChannel discord.ChannelID `json:"channel_id,omitempty"` } // ModifyMember modifies attributes of a guild member. If the channel_id is set // to null, this will force the target user to be disconnected from voice. // // Fires a Guild Member Update Gateway event. -func (c *Client) ModifyMember(guildID, userID discord.Snowflake, data ModifyMemberData) error { +func (c *Client) ModifyMember(guildID discord.GuildID, userID discord.UserID, data ModifyMemberData) error { return c.FastRequest( "PATCH", @@ -179,7 +179,7 @@ type PruneCountData struct { // Days is the number of days to count prune for (1 or more, default 7). Days uint `schema:"days"` // IncludedRoles are the role(s) to include. - IncludedRoles []discord.Snowflake `schema:"include_roles,omitempty"` + IncludedRoles []discord.RoleID `schema:"include_roles,omitempty"` } // PruneCount returns the number of members that would be removed in a prune @@ -191,7 +191,7 @@ type PruneCountData struct { // will be counted in the prune and users with additional roles will not. // // Requires KICK_MEMBERS. -func (c *Client) PruneCount(guildID discord.Snowflake, data PruneCountData) (uint, error) { +func (c *Client) PruneCount(guildID discord.GuildID, data PruneCountData) (uint, error) { if data.Days == 0 { data.Days = 7 } @@ -215,7 +215,7 @@ type PruneData struct { // large guilds. ReturnCount bool `schema:"compute_prune_count"` // IncludedRoles are the role(s) to include. - IncludedRoles []discord.Snowflake `schema:"include_roles,omitempty"` + IncludedRoles []discord.RoleID `schema:"include_roles,omitempty"` } // Prune begins a prune. Days must be 1 or more, default 7. @@ -227,7 +227,7 @@ type PruneData struct { // // Requires KICK_MEMBERS. // Fires multiple Guild Member Remove Gateway events. -func (c *Client) Prune(guildID discord.Snowflake, data PruneData) (uint, error) { +func (c *Client) Prune(guildID discord.GuildID, data PruneData) (uint, error) { if data.Days == 0 { data.Days = 7 } @@ -247,7 +247,7 @@ func (c *Client) Prune(guildID discord.Snowflake, data PruneData) (uint, error) // // Requires KICK_MEMBERS permission. // Fires a Guild Member Remove Gateway event. -func (c *Client) Kick(guildID, userID discord.Snowflake) error { +func (c *Client) Kick(guildID discord.GuildID, userID discord.UserID) error { return c.FastRequest( "DELETE", EndpointGuilds+guildID.String()+"/members/"+userID.String(), @@ -257,7 +257,7 @@ func (c *Client) Kick(guildID, userID discord.Snowflake) error { // Bans returns a list of ban objects for the users banned from this guild. // // Requires the BAN_MEMBERS permission. -func (c *Client) Bans(guildID discord.Snowflake) ([]discord.Ban, error) { +func (c *Client) Bans(guildID discord.GuildID) ([]discord.Ban, error) { var bans []discord.Ban return bans, c.RequestJSON( &bans, "GET", @@ -268,7 +268,7 @@ func (c *Client) Bans(guildID discord.Snowflake) ([]discord.Ban, error) { // GetBan returns a ban object for the given user. // // Requires the BAN_MEMBERS permission. -func (c *Client) GetBan(guildID, userID discord.Snowflake) (*discord.Ban, error) { +func (c *Client) GetBan(guildID discord.GuildID, userID discord.UserID) (*discord.Ban, error) { var ban *discord.Ban return ban, c.RequestJSON( &ban, "GET", @@ -288,7 +288,7 @@ type BanData struct { // banned user. // // Requires the BAN_MEMBERS permission. -func (c *Client) Ban(guildID, userID discord.Snowflake, data BanData) error { +func (c *Client) Ban(guildID discord.GuildID, userID discord.UserID, data BanData) error { return c.FastRequest( "PUT", EndpointGuilds+guildID.String()+"/bans/"+userID.String(), @@ -300,6 +300,6 @@ func (c *Client) Ban(guildID, userID discord.Snowflake, data BanData) error { // // Requires the BAN_MEMBERS permissions. // Fires a Guild Ban Remove Gateway event. -func (c *Client) Unban(guildID, userID discord.Snowflake) error { +func (c *Client) Unban(guildID discord.GuildID, userID discord.UserID) error { return c.FastRequest("DELETE", EndpointGuilds+guildID.String()+"/bans/"+userID.String()) } diff --git a/api/message.go b/api/message.go index ca5de8d..1e64908 100644 --- a/api/message.go +++ b/api/message.go @@ -18,13 +18,13 @@ import ( // // When fetching the messages, those with the smallest ID will be fetched // first. -func (c *Client) Messages(channelID discord.Snowflake, limit uint) ([]discord.Message, error) { +func (c *Client) Messages(channelID discord.ChannelID, limit uint) ([]discord.Message, error) { return c.MessagesAfter(channelID, 0, limit) } // MessagesAround returns messages around the ID, with a limit of 100. func (c *Client) MessagesAround( - channelID, around discord.Snowflake, limit uint) ([]discord.Message, error) { + channelID discord.ChannelID, around discord.MessageID, limit uint) ([]discord.Message, error) { return c.messagesRange(channelID, 0, 0, around, limit) } @@ -38,7 +38,7 @@ func (c *Client) MessagesAround( // maximum a total of limit/100 rounded up requests will be made, although they // may be less, if no more messages are available. func (c *Client) MessagesBefore( - channelID, before discord.Snowflake, limit uint) ([]discord.Message, error) { + channelID discord.ChannelID, before discord.MessageID, limit uint) ([]discord.Message, error) { var msgs []discord.Message @@ -80,7 +80,7 @@ func (c *Client) MessagesBefore( // maximum a total of limit/100 rounded up requests will be made, although they // may be less, if no more messages are available. func (c *Client) MessagesAfter( - channelID, after discord.Snowflake, limit uint) ([]discord.Message, error) { + channelID discord.ChannelID, after discord.MessageID, limit uint) ([]discord.Message, error) { var msgs []discord.Message @@ -114,7 +114,7 @@ func (c *Client) MessagesAfter( } func (c *Client) messagesRange( - channelID, before, after, around discord.Snowflake, limit uint) ([]discord.Message, error) { + channelID discord.ChannelID, before, after, around discord.MessageID, limit uint) ([]discord.Message, error) { switch { case limit == 0: @@ -124,9 +124,9 @@ func (c *Client) messagesRange( } var param struct { - Before discord.Snowflake `schema:"before,omitempty"` - After discord.Snowflake `schema:"after,omitempty"` - Around discord.Snowflake `schema:"around,omitempty"` + Before discord.MessageID `schema:"before,omitempty"` + After discord.MessageID `schema:"after,omitempty"` + Around discord.MessageID `schema:"around,omitempty"` Limit uint `schema:"limit"` } @@ -148,7 +148,7 @@ func (c *Client) messagesRange( // // If operating on a guild channel, this endpoint requires the // READ_MESSAGE_HISTORY permission to be present on the current user. -func (c *Client) Message(channelID, messageID discord.Snowflake) (*discord.Message, error) { +func (c *Client) Message(channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) { var msg *discord.Message return msg, c.RequestJSON(&msg, "GET", EndpointChannels+channelID.String()+"/messages/"+messageID.String()) @@ -160,7 +160,7 @@ func (c *Client) Message(channelID, messageID discord.Snowflake) (*discord.Messa // permission to be present on the current user. // // Fires a Message Create Gateway event. -func (c *Client) SendText(channelID discord.Snowflake, content string) (*discord.Message, error) { +func (c *Client) SendText(channelID discord.ChannelID, content string) (*discord.Message, error) { return c.SendMessageComplex(channelID, SendMessageData{ Content: content, }) @@ -173,7 +173,7 @@ func (c *Client) SendText(channelID discord.Snowflake, content string) (*discord // // Fires a Message Create Gateway event. func (c *Client) SendEmbed( - channelID discord.Snowflake, e discord.Embed) (*discord.Message, error) { + channelID discord.ChannelID, e discord.Embed) (*discord.Message, error) { return c.SendMessageComplex(channelID, SendMessageData{ Embed: &e, @@ -187,7 +187,7 @@ func (c *Client) SendEmbed( // // Fires a Message Create Gateway event. func (c *Client) SendMessage( - channelID discord.Snowflake, content string, embed *discord.Embed) (*discord.Message, error) { + channelID discord.ChannelID, content string, embed *discord.Embed) (*discord.Message, error) { return c.SendMessageComplex(channelID, SendMessageData{ Content: content, @@ -213,7 +213,7 @@ type EditMessageData struct { // EditText edits the contents of a previously sent message. For more // documentation, refer to EditMessageComplex. func (c *Client) EditText( - channelID, messageID discord.Snowflake, content string) (*discord.Message, error) { + channelID discord.ChannelID, messageID discord.MessageID, content string) (*discord.Message, error) { return c.EditMessageComplex(channelID, messageID, EditMessageData{ Content: option.NewNullableString(content), @@ -223,7 +223,7 @@ func (c *Client) EditText( // EditEmbed edits the embed of a previously sent message. For more // documentation, refer to EditMessageComplex. func (c *Client) EditEmbed( - channelID, messageID discord.Snowflake, embed discord.Embed) (*discord.Message, error) { + channelID discord.ChannelID, messageID discord.MessageID, embed discord.Embed) (*discord.Message, error) { return c.EditMessageComplex(channelID, messageID, EditMessageData{ Embed: &embed, @@ -233,7 +233,7 @@ func (c *Client) EditEmbed( // EditMessage edits a previously sent message. For more documentation, refer to // EditMessageComplex. func (c *Client) EditMessage( - channelID, messageID discord.Snowflake, content string, + channelID discord.ChannelID, messageID discord.MessageID, content string, embed *discord.Embed, suppressEmbeds bool) (*discord.Message, error) { var data = EditMessageData{ @@ -258,7 +258,7 @@ func (c *Client) EditMessage( // // Fires a Message Update Gateway event. func (c *Client) EditMessageComplex( - channelID, messageID discord.Snowflake, data EditMessageData) (*discord.Message, error) { + channelID discord.ChannelID, messageID discord.MessageID, data EditMessageData) (*discord.Message, error) { if data.AllowedMentions != nil { if err := data.AllowedMentions.Verify(); err != nil { @@ -283,7 +283,7 @@ func (c *Client) EditMessageComplex( // DeleteMessage delete a message. If operating on a guild channel and trying // to delete a message that was not sent by the current user, this endpoint // requires the MANAGE_MESSAGES permission. -func (c *Client) DeleteMessage(channelID, messageID discord.Snowflake) error { +func (c *Client) DeleteMessage(channelID discord.ChannelID, messageID discord.MessageID) error { return c.FastRequest("DELETE", EndpointChannels+channelID.String()+ "/messages/"+messageID.String()) } @@ -297,9 +297,9 @@ func (c *Client) DeleteMessage(channelID, messageID discord.Snowflake) error { // provided. // // Fires a Message Delete Bulk Gateway event. -func (c *Client) DeleteMessages(channelID discord.Snowflake, messageIDs []discord.Snowflake) error { +func (c *Client) DeleteMessages(channelID discord.ChannelID, messageIDs []discord.MessageID) error { var param struct { - Messages []discord.Snowflake `json:"messages"` + Messages []discord.MessageID `json:"messages"` } param.Messages = messageIDs diff --git a/api/message_reaction.go b/api/message_reaction.go index 023d6d0..44ea28b 100644 --- a/api/message_reaction.go +++ b/api/message_reaction.go @@ -13,7 +13,7 @@ import ( // the current user. Additionally, if nobody else has reacted to the message // using this emoji, this endpoint requires the 'ADD_REACTIONS' permission to // be present on the current user. -func (c *Client) React(channelID, messageID discord.Snowflake, emoji Emoji) error { +func (c *Client) React(channelID discord.ChannelID, messageID discord.MessageID, emoji Emoji) error { var msgURL = EndpointChannels + channelID.String() + "/messages/" + messageID.String() + "/reactions/" + url.PathEscape(emoji) + "/@me" @@ -21,7 +21,7 @@ func (c *Client) React(channelID, messageID discord.Snowflake, emoji Emoji) erro } // Unreact removes a reaction the current user has made for the message. -func (c *Client) Unreact(chID, msgID discord.Snowflake, emoji Emoji) error { +func (c *Client) Unreact(chID discord.ChannelID, msgID discord.MessageID, emoji Emoji) error { return c.DeleteUserReaction(chID, msgID, 0, emoji) } @@ -35,7 +35,7 @@ func (c *Client) Unreact(chID, msgID discord.Snowflake, emoji Emoji) error { // // When fetching the users, those with the smallest ID will be fetched first. func (c *Client) Reactions( - channelID, messageID discord.Snowflake, emoji Emoji, limit uint) ([]discord.User, error) { + channelID discord.ChannelID, messageID discord.MessageID, emoji Emoji, limit uint) ([]discord.User, error) { return c.ReactionsAfter(channelID, messageID, 0, emoji, limit) } @@ -48,7 +48,7 @@ func (c *Client) Reactions( // maximum a total of limit/100 rounded up requests will be made, although they // may be less, if no more guilds are available. func (c *Client) ReactionsBefore( - channelID, messageID, before discord.Snowflake, emoji Emoji, + channelID discord.ChannelID, messageID discord.MessageID, before discord.UserID, emoji Emoji, limit uint) ([]discord.User, error) { var users []discord.User @@ -89,7 +89,7 @@ func (c *Client) ReactionsBefore( // maximum a total of limit/100 rounded up requests will be made, although they // may be less, if no more guilds are available. func (c *Client) ReactionsAfter( - channelID, messageID, after discord.Snowflake, emoji Emoji, + channelID discord.ChannelID, messageID discord.MessageID, after discord.UserID, emoji Emoji, limit uint) ([]discord.User, error) { var users []discord.User @@ -125,7 +125,7 @@ func (c *Client) ReactionsAfter( // reactionsRange get users before and after IDs. Before, after, and limit are // optional. A maximum limit of only 100 reactions could be returned. func (c *Client) reactionsRange( - channelID, messageID, before, after discord.Snowflake, emoji Emoji, + channelID discord.ChannelID, messageID discord.MessageID, before, after discord.UserID, emoji Emoji, limit uint) ([]discord.User, error) { switch { @@ -136,8 +136,8 @@ func (c *Client) reactionsRange( } var param struct { - Before discord.Snowflake `schema:"before,omitempty"` - After discord.Snowflake `schema:"after,omitempty"` + Before discord.UserID `schema:"before,omitempty"` + After discord.UserID `schema:"after,omitempty"` Limit uint `schema:"limit"` } @@ -160,7 +160,7 @@ func (c *Client) reactionsRange( // This endpoint requires the MANAGE_MESSAGES permission to be present on the // current user. func (c *Client) DeleteUserReaction( - channelID, messageID, userID discord.Snowflake, emoji Emoji) error { + channelID discord.ChannelID, messageID discord.MessageID, userID discord.UserID, emoji Emoji) error { var user = "@me" if userID > 0 { @@ -180,7 +180,7 @@ func (c *Client) DeleteUserReaction( // current user. // Fires a Message Reaction Remove Emoji Gateway event. func (c *Client) DeleteReactions( - channelID, messageID discord.Snowflake, emoji Emoji) error { + channelID discord.ChannelID, messageID discord.MessageID, emoji Emoji) error { return c.FastRequest( "DELETE", @@ -194,7 +194,7 @@ func (c *Client) DeleteReactions( // This endpoint requires the MANAGE_MESSAGES permission to be present on the // current user. // Fires a Message Reaction Remove All Gateway event. -func (c *Client) DeleteAllReactions(channelID, messageID discord.Snowflake) error { +func (c *Client) DeleteAllReactions(channelID discord.ChannelID, messageID discord.MessageID) error { return c.FastRequest( "DELETE", EndpointChannels+channelID.String()+"/messages/"+messageID.String()+"/reactions/", diff --git a/api/role.go b/api/role.go index 1d8d83d..5ea2d6f 100644 --- a/api/role.go +++ b/api/role.go @@ -9,7 +9,7 @@ import ( // Adds a role to a guild member. // // Requires the MANAGE_ROLES permission. -func (c *Client) AddRole(guildID, userID, roleID discord.Snowflake) error { +func (c *Client) AddRole(guildID discord.GuildID, userID discord.UserID, roleID discord.RoleID) error { return c.FastRequest( "PUT", EndpointGuilds+guildID.String()+"/members/"+userID.String()+"/roles/"+roleID.String(), @@ -20,7 +20,7 @@ func (c *Client) AddRole(guildID, userID, roleID discord.Snowflake) error { // // Requires the MANAGE_ROLES permission. // Fires a Guild Member Update Gateway event. -func (c *Client) RemoveRole(guildID, userID, roleID discord.Snowflake) error { +func (c *Client) RemoveRole(guildID discord.GuildID, userID discord.UserID, roleID discord.RoleID) error { return c.FastRequest( "DELETE", EndpointGuilds+guildID.String()+"/members/"+userID.String()+"/roles/"+roleID.String(), @@ -28,7 +28,7 @@ func (c *Client) RemoveRole(guildID, userID, roleID discord.Snowflake) error { } // Roles returns a list of role objects for the guild. -func (c *Client) Roles(guildID discord.Snowflake) ([]discord.Role, error) { +func (c *Client) Roles(guildID discord.GuildID) ([]discord.Role, error) { var roles []discord.Role return roles, c.RequestJSON(&roles, "GET", EndpointGuilds+guildID.String()+"/roles") } @@ -62,8 +62,7 @@ type CreateRoleData struct { // // Requires the MANAGE_ROLES permission. // Fires a Guild Role Create Gateway event. -func (c *Client) CreateRole( - guildID discord.Snowflake, data CreateRoleData) (*discord.Role, error) { +func (c *Client) CreateRole(guildID discord.GuildID, data CreateRoleData) (*discord.Role, error) { var role *discord.Role return role, c.RequestJSON( @@ -76,7 +75,7 @@ func (c *Client) CreateRole( // https://discord.com/developers/docs/resources/guild#modify-guild-role-positions-json-params type MoveRoleData struct { // ID is the id of the role. - ID discord.Snowflake `json:"id"` + ID discord.RoleID `json:"id"` // Position is the sorting position of the role. Position option.NullableInt `json:"position,omitempty"` } @@ -85,7 +84,7 @@ type MoveRoleData struct { // // Requires the MANAGE_ROLES permission. // Fires multiple Guild Role Update Gateway events. -func (c *Client) MoveRole(guildID discord.Snowflake, data []MoveRoleData) ([]discord.Role, error) { +func (c *Client) MoveRole(guildID discord.GuildID, data []MoveRoleData) ([]discord.Role, error) { var roles []discord.Role return roles, c.RequestJSON( &roles, "PATCH", @@ -113,7 +112,7 @@ type ModifyRoleData struct { // // Requires the MANAGE_ROLES permission. func (c *Client) ModifyRole( - guildID, roleID discord.Snowflake, + guildID discord.GuildID, roleID discord.RoleID, data ModifyRoleData) (*discord.Role, error) { var role *discord.Role @@ -127,7 +126,7 @@ func (c *Client) ModifyRole( // DeleteRole deletes a guild role. // // Requires the MANAGE_ROLES permission. -func (c *Client) DeleteRole(guildID, roleID discord.Snowflake) error { +func (c *Client) DeleteRole(guildID discord.GuildID, roleID discord.RoleID) error { return c.FastRequest( "DELETE", EndpointGuilds+guildID.String()+"/roles/"+roleID.String(), diff --git a/api/send.go b/api/send.go index e8d534e..3455165 100644 --- a/api/send.go +++ b/api/send.go @@ -41,9 +41,9 @@ type AllowedMentions struct { // Parse is an array of allowed mention types to parse from the content. Parse []AllowedMentionType `json:"parse"` // Roles is an array of role_ids to mention (Max size of 100). - Roles []discord.Snowflake `json:"roles,omitempty"` + Roles []discord.RoleID `json:"roles,omitempty"` // Users is an array of user_ids to mention (Max size of 100). - Users []discord.Snowflake `json:"users,omitempty"` + Users []discord.UserID `json:"users,omitempty"` } // AllowedMentionType is a constant that tells Discord what is allowed to parse @@ -138,7 +138,7 @@ func (data *SendMessageData) WriteMultipart(body *multipart.Writer) error { // least one of content, embed or file. For a file attachment, the // Content-Disposition subpart header MUST contain a filename parameter. func (c *Client) SendMessageComplex( - channelID discord.Snowflake, data SendMessageData) (*discord.Message, error) { + channelID discord.ChannelID, data SendMessageData) (*discord.Message, error) { if data.Content == "" && data.Embed == nil && len(data.Files) == 0 { return nil, ErrEmptyMessage @@ -211,7 +211,7 @@ func (data *ExecuteWebhookData) WriteMultipart(body *multipart.Writer) error { // wait for the message to be delivered and will return the message body. This // also means the returned message will only be there if wait is true. func (c *Client) ExecuteWebhook( - webhookID discord.Snowflake, + webhookID discord.WebhookID, token string, wait bool, // if false, then nil returned for *Message. data ExecuteWebhookData) (*discord.Message, error) { diff --git a/api/send_test.go b/api/send_test.go index c2ffe10..7aef2db 100644 --- a/api/send_test.go +++ b/api/send_test.go @@ -34,7 +34,7 @@ func TestMarshalAllowedMentions(t *testing.T) { t.Run("allow certain user IDs", func(t *testing.T) { var data = SendMessageData{ AllowedMentions: &AllowedMentions{ - Users: []discord.Snowflake{1, 2}, + Users: []discord.UserID{1, 2}, }, } @@ -48,7 +48,7 @@ func TestVerifyAllowedMentions(t *testing.T) { t.Run("invalid", func(t *testing.T) { var am = AllowedMentions{ Parse: []AllowedMentionType{AllowEveryoneMention, AllowUserMention}, - Users: []discord.Snowflake{69, 420}, + Users: []discord.UserID{69, 420}, } err := am.Verify() @@ -57,7 +57,7 @@ func TestVerifyAllowedMentions(t *testing.T) { t.Run("users too long", func(t *testing.T) { var am = AllowedMentions{ - Users: make([]discord.Snowflake, 101), + Users: make([]discord.UserID, 101), } err := am.Verify() @@ -66,7 +66,7 @@ func TestVerifyAllowedMentions(t *testing.T) { t.Run("roles too long", func(t *testing.T) { var am = AllowedMentions{ - Roles: make([]discord.Snowflake, 101), + Roles: make([]discord.RoleID, 101), } err := am.Verify() @@ -76,8 +76,8 @@ func TestVerifyAllowedMentions(t *testing.T) { t.Run("valid", func(t *testing.T) { var am = AllowedMentions{ Parse: []AllowedMentionType{AllowEveryoneMention, AllowUserMention}, - Roles: []discord.Snowflake{1337}, - Users: []discord.Snowflake{}, + Roles: []discord.RoleID{1337}, + Users: []discord.UserID{}, } if err := am.Verify(); err != nil { @@ -125,7 +125,7 @@ func TestSendMessage(t *testing.T) { Content: "hime arikawa", AllowedMentions: &AllowedMentions{ Parse: []AllowedMentionType{AllowEveryoneMention, AllowUserMention}, - Users: []discord.Snowflake{69, 420}, + Users: []discord.UserID{69, 420}, }, } diff --git a/api/user.go b/api/user.go index 037e684..504d706 100644 --- a/api/user.go +++ b/api/user.go @@ -12,7 +12,7 @@ var ( ) // User returns a user object for a given user ID. -func (c *Client) User(userID discord.Snowflake) (*discord.User, error) { +func (c *Client) User(userID discord.UserID) (*discord.User, error) { var u *discord.User return u, c.RequestJSON(&u, "GET", EndpointUsers+userID.String()) } @@ -44,7 +44,7 @@ func (c *Client) ModifyMe(data ModifySelfData) (*discord.User, error) { // // Fires a Guild Member Update Gateway event. func (c *Client) ChangeOwnNickname( - guildID discord.Snowflake, nick string) error { + guildID discord.GuildID, nick string) error { var param struct { Nick string `json:"nick"` @@ -68,9 +68,9 @@ func (c *Client) PrivateChannels() ([]discord.Channel, error) { } // CreatePrivateChannel creates a new DM channel with a user. -func (c *Client) CreatePrivateChannel(recipientID discord.Snowflake) (*discord.Channel, error) { +func (c *Client) CreatePrivateChannel(recipientID discord.UserID) (*discord.Channel, error) { var param struct { - RecipientID discord.Snowflake `json:"recipient_id"` + RecipientID discord.UserID `json:"recipient_id"` } param.RecipientID = recipientID @@ -88,7 +88,7 @@ func (c *Client) UserConnections() ([]discord.Connection, error) { // SetNote sets a note for the user. This endpoint is undocumented and might // only work for user accounts. -func (c *Client) SetNote(userID discord.Snowflake, note string) error { +func (c *Client) SetNote(userID discord.UserID, note string) error { var body = struct { Note string `json:"note"` }{ @@ -103,7 +103,7 @@ func (c *Client) SetNote(userID discord.Snowflake, note string) error { // SetRelationship sets the relationship type between the current user and the // given user. -func (c *Client) SetRelationship(userID discord.Snowflake, t discord.RelationshipType) error { +func (c *Client) SetRelationship(userID discord.UserID, t discord.RelationshipType) error { var body = struct { Type discord.RelationshipType `json:"type"` }{ @@ -118,6 +118,6 @@ func (c *Client) SetRelationship(userID discord.Snowflake, t discord.Relationshi // DeleteRelationship deletes the relationship between the current user and the // given user. -func (c *Client) DeleteRelationship(userID discord.Snowflake) error { +func (c *Client) DeleteRelationship(userID discord.UserID) error { return c.FastRequest("DELETE", EndpointMe+"/relationships/"+userID.String()) } diff --git a/api/webhook.go b/api/webhook.go index d420795..49a086f 100644 --- a/api/webhook.go +++ b/api/webhook.go @@ -22,7 +22,7 @@ type CreateWebhookData struct { // // Requires the MANAGE_WEBHOOKS permission. func (c *Client) CreateWebhook( - channelID discord.Snowflake, data CreateWebhookData) (*discord.Webhook, error) { + channelID discord.ChannelID, data CreateWebhookData) (*discord.Webhook, error) { var w *discord.Webhook return w, c.RequestJSON( @@ -35,7 +35,7 @@ func (c *Client) CreateWebhook( // ChannelWebhooks returns the webhooks of the channel with the given ID. // // Requires the MANAGE_WEBHOOKS permission. -func (c *Client) ChannelWebhooks(channelID discord.Snowflake) ([]discord.Webhook, error) { +func (c *Client) ChannelWebhooks(channelID discord.ChannelID) ([]discord.Webhook, error) { var ws []discord.Webhook return ws, c.RequestJSON(&ws, "GET", EndpointChannels+channelID.String()+"/webhooks") } @@ -43,13 +43,13 @@ func (c *Client) ChannelWebhooks(channelID discord.Snowflake) ([]discord.Webhook // GuildWebhooks returns the webhooks of the guild with the given ID. // // Requires the MANAGE_WEBHOOKS permission. -func (c *Client) GuildWebhooks(guildID discord.Snowflake) ([]discord.Webhook, error) { +func (c *Client) GuildWebhooks(guildID discord.GuildID) ([]discord.Webhook, error) { var ws []discord.Webhook return ws, c.RequestJSON(&ws, "GET", EndpointGuilds+guildID.String()+"/webhooks") } // Webhook returns the webhook with the given id. -func (c *Client) Webhook(webhookID discord.Snowflake) (*discord.Webhook, error) { +func (c *Client) Webhook(webhookID discord.WebhookID) (*discord.Webhook, error) { var w *discord.Webhook return w, c.RequestJSON(&w, "GET", EndpointWebhooks+webhookID.String()) } @@ -57,7 +57,7 @@ func (c *Client) Webhook(webhookID discord.Snowflake) (*discord.Webhook, error) // WebhookWithToken is the same as above, except this call does not require // authentication and returns no user in the webhook object. func (c *Client) WebhookWithToken( - webhookID discord.Snowflake, token string) (*discord.Webhook, error) { + webhookID discord.WebhookID, token string) (*discord.Webhook, error) { var w *discord.Webhook return w, c.RequestJSON(&w, "GET", EndpointWebhooks+webhookID.String()+"/"+token) @@ -70,14 +70,14 @@ type ModifyWebhookData struct { // Avatar is the image for the default webhook avatar. Avatar *Image `json:"avatar,omitempty"` // ChannelID is the new channel id this webhook should be moved to. - ChannelID discord.Snowflake `json:"channel_id,omitempty"` + ChannelID discord.ChannelID `json:"channel_id,omitempty"` } // ModifyWebhook modifies a webhook. // // Requires the MANAGE_WEBHOOKS permission. func (c *Client) ModifyWebhook( - webhookID discord.Snowflake, data ModifyWebhookData) (*discord.Webhook, error) { + webhookID discord.WebhookID, data ModifyWebhookData) (*discord.Webhook, error) { var w *discord.Webhook return w, c.RequestJSON( @@ -91,7 +91,7 @@ func (c *Client) ModifyWebhook( // require authentication, does not accept a channel_id parameter in the body, // and does not return a user in the webhook object. func (c *Client) ModifyWebhookWithToken( - webhookID discord.Snowflake, token string, data ModifyWebhookData) (*discord.Webhook, error) { + webhookID discord.WebhookID, token string, data ModifyWebhookData) (*discord.Webhook, error) { var w *discord.Webhook return w, c.RequestJSON( @@ -104,12 +104,12 @@ func (c *Client) ModifyWebhookWithToken( // DeleteWebhook deletes a webhook permanently. // // Requires the MANAGE_WEBHOOKS permission. -func (c *Client) DeleteWebhook(webhookID discord.Snowflake) error { +func (c *Client) DeleteWebhook(webhookID discord.WebhookID) error { return c.FastRequest("DELETE", EndpointWebhooks+webhookID.String()) } // DeleteWebhookWithToken is the same as above, except this call does not // require authentication. -func (c *Client) DeleteWebhookWithToken(webhookID discord.Snowflake, token string) error { +func (c *Client) DeleteWebhookWithToken(webhookID discord.WebhookID, token string) error { return c.FastRequest("DELETE", EndpointWebhooks+webhookID.String()+"/"+token) } diff --git a/bot/extras/arguments/emoji.go b/bot/extras/arguments/emoji.go index 796c064..1cccbc1 100644 --- a/bot/extras/arguments/emoji.go +++ b/bot/extras/arguments/emoji.go @@ -15,7 +15,7 @@ var ( ) type Emoji struct { - ID discord.Snowflake + ID discord.EmojiID Name string Custom bool @@ -83,7 +83,7 @@ func (e *Emoji) Parse(arg string) error { e.Custom = true e.Animated = matches[1] == "a" e.Name = matches[2] - e.ID = id + e.ID = discord.EmojiID(id) return nil } diff --git a/bot/extras/arguments/link.go b/bot/extras/arguments/link.go index 9e7afa2..d57e692 100644 --- a/bot/extras/arguments/link.go +++ b/bot/extras/arguments/link.go @@ -17,9 +17,9 @@ var Regex = regexp.MustCompile( // MessageURL contains info from a MessageURL type MessageURL struct { - GuildID discord.Snowflake - ChannelID discord.Snowflake - MessageID discord.Snowflake + GuildID discord.GuildID + ChannelID discord.ChannelID + MessageID discord.MessageID } func (url *MessageURL) Parse(arg string) error { @@ -55,8 +55,8 @@ func ParseMessageURL(url string) *MessageURL { } return &MessageURL{ - GuildID: gID, - ChannelID: cID, - MessageID: mID, + GuildID: discord.GuildID(gID), + ChannelID: discord.ChannelID(cID), + MessageID: discord.MessageID(mID), } } diff --git a/bot/extras/arguments/mention.go b/bot/extras/arguments/mention.go index 062e1de..72c606f 100644 --- a/bot/extras/arguments/mention.go +++ b/bot/extras/arguments/mention.go @@ -15,7 +15,7 @@ var ( // -type ChannelMention discord.Snowflake +type ChannelMention discord.ChannelID func (m *ChannelMention) Parse(arg string) error { return grabFirst(ChannelRegex, "channel mention", arg, (*discord.Snowflake)(m)) @@ -35,7 +35,7 @@ func (m *ChannelMention) Mention() string { // -type UserMention discord.Snowflake +type UserMention discord.UserID func (m *UserMention) Parse(arg string) error { return grabFirst(UserRegex, "user mention", arg, (*discord.Snowflake)(m)) @@ -55,7 +55,7 @@ func (m *UserMention) Mention() string { // -type RoleMention discord.Snowflake +type RoleMention discord.RoleID func (m *RoleMention) Parse(arg string) error { return grabFirst(RoleRegex, "role mention", arg, (*discord.Snowflake)(m)) diff --git a/bot/extras/infer/infer.go b/bot/extras/infer/infer.go index 8facefd..b03b80f 100644 --- a/bot/extras/infer/infer.go +++ b/bot/extras/infer/infer.go @@ -13,21 +13,21 @@ import ( // ChannelID looks for fields with name ChannelID, Channel, or in some special // cases, ID. -func ChannelID(event interface{}) discord.Snowflake { - return reflectID(reflect.ValueOf(event), "Channel") +func ChannelID(event interface{}) discord.ChannelID { + return discord.ChannelID(reflectID(reflect.ValueOf(event), "Channel")) } // GuildID looks for fields with name GuildID, Guild, or in some special cases, // ID. -func GuildID(event interface{}) discord.Snowflake { - return reflectID(reflect.ValueOf(event), "Guild") +func GuildID(event interface{}) discord.GuildID { + return discord.GuildID(reflectID(reflect.ValueOf(event), "Guild")) } // UserID looks for fields with name UserID, User, or in some special cases, ID. -func UserID(event interface{}) discord.Snowflake { +func UserID(event interface{}) discord.UserID { // This may have a very fatal bug of accidentally mistaking another User's // ID. It also probably wouldn't work with things like RecipientID. - return reflectID(reflect.ValueOf(event), "User") + return discord.UserID(reflectID(reflect.ValueOf(event), "User")) } func reflectID(v reflect.Value, thing string) discord.Snowflake { diff --git a/bot/extras/infer/infer_test.go b/bot/extras/infer/infer_test.go index 04eaf9a..ab054a6 100644 --- a/bot/extras/infer/infer_test.go +++ b/bot/extras/infer/infer_test.go @@ -7,7 +7,7 @@ import ( ) type hasID struct { - ChannelID discord.Snowflake + ChannelID discord.ChannelID } type embedsID struct { @@ -16,7 +16,7 @@ type embedsID struct { } type hasChannelInName struct { - ID discord.Snowflake + ID discord.ChannelID } func TestReflectChannelID(t *testing.T) { diff --git a/bot/extras/middlewares/middlewares_test.go b/bot/extras/middlewares/middlewares_test.go index fa69d08..454d68f 100644 --- a/bot/extras/middlewares/middlewares_test.go +++ b/bot/extras/middlewares/middlewares_test.go @@ -162,7 +162,7 @@ type mockStore struct { state.NoopStore } -func (s *mockStore) Guild(id discord.Snowflake) (*discord.Guild, error) { +func (s *mockStore) Guild(id discord.GuildID) (*discord.Guild, error) { return &discord.Guild{ ID: id, Roles: []discord.Role{{ @@ -172,23 +172,23 @@ func (s *mockStore) Guild(id discord.Snowflake) (*discord.Guild, error) { }, nil } -func (s *mockStore) Member(g, m discord.Snowflake) (*discord.Member, error) { +func (s *mockStore) Member(guildID discord.GuildID, userID discord.UserID) (*discord.Member, error) { return &discord.Member{ - User: discord.User{ID: m}, - RoleIDs: []discord.Snowflake{m}, + User: discord.User{ID: userID}, + RoleIDs: []discord.RoleID{discord.RoleID(userID)}, }, nil } // Channel returns a channel with a guildID for #69420. -func (s *mockStore) Channel(chID discord.Snowflake) (*discord.Channel, error) { - if chID == 69420 { +func (s *mockStore) Channel(id discord.ChannelID) (*discord.Channel, error) { + if id == 69420 { return &discord.Channel{ - ID: chID, + ID: id, GuildID: 1337, }, nil } return &discord.Channel{ - ID: chID, + ID: id, }, nil } diff --git a/discord/auditlog.go b/discord/auditlog.go index 228ab25..e1de2ea 100644 --- a/discord/auditlog.go +++ b/discord/auditlog.go @@ -24,13 +24,13 @@ type AuditLog struct { // https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object type AuditLogEntry struct { // ID is the id of the entry. - ID Snowflake `json:"id"` + ID AuditLogEntryID `json:"id"` // TargetID is the id of the affected entity (webhook, user, role, etc.). TargetID string `json:"target_id,omitempty"` // Changes are the changes made to the TargetID. Changes []AuditLogChange `json:"changes,omitempty"` // UserID is the id of the user who made the changes. - UserID Snowflake `json:"user_id"` + UserID UserID `json:"user_id"` // ActionType is the type of action that occurred. ActionType AuditLogEvent `json:"action_type"` @@ -97,11 +97,11 @@ type AuditEntryInfo struct { // ChannelID is the id of the channel in which the entities were targeted. // // Events: MEMBER_MOVE, MESSAGE_PIN, MESSAGE_UNPIN, MESSAGE_DELETE - ChannelID Snowflake `json:"channel_id,omitempty"` + ChannelID ChannelID `json:"channel_id,omitempty"` // MessagesID is the id of the message that was targeted. // // Events: MESSAGE_PIN, MESSAGE_UNPIN - MessageID Snowflake `json:"message_id,omitempty"` + MessageID MessageID `json:"message_id,omitempty"` // Count is the number of entities that were targeted. // // Events: MESSAGE_DELETE, MESSAGE_BULK_DELETE, MEMBER_DISCONNECT, @@ -151,8 +151,8 @@ const ( // return errors.New("not owner ID") // } // -// // We know these are snowflakes because the comment said so for AuditGuildOwnerID. -// var oldOwnerID, newOwnerID discord.Snowflake +// // We know these are UserIDs because the comment said so for AuditGuildOwnerID. +// var oldOwnerID, newOwnerID discord.UserID // if err := change.UnmarshalValues(&oldOwnerID, &newOwnerID); err != nil { // return err // } @@ -199,7 +199,7 @@ const ( AuditGuildSplashHash AuditLogChangeKey = "splash_hash" // AuditGuildOwnerID gets sent if the guild's owner changed. // - // Type: Snowflake + // Type: UserID AuditGuildOwnerID AuditLogChangeKey = "owner_id" // AuditGuildRegion gets sent if the guild's region changed. // @@ -207,7 +207,7 @@ const ( AuditGuildRegion AuditLogChangeKey = "region" // AuditGuildAFKChannelID gets sent if the guild's afk channel changed. // - // Type: Snowflake + // Type: ChannelID AuditGuildAFKChannelID AuditLogChangeKey = "afk_channel_id" // AuditGuildAFKTimeout gets sent if the guild's afk timeout duration // changed. @@ -259,12 +259,12 @@ const ( // AuditGuildWidgetChannelID gets sent if the channel ID of the guild // widget changed. // - // Type: Snowflake + // Type: ChannelID AuditGuildWidgetChannelID AuditLogChangeKey = "widget_channel_id" // AuditGuildSystemChannelID gets sent if the ID of the guild's system // channel changed. // - // Type: Snowflake + // Type: ChannelID AuditGuildSystemChannelID AuditLogChangeKey = "system_channel_id" ) @@ -294,7 +294,7 @@ const ( // AuditChannelApplicationID contains the application ID of the added or // removed webhook or bot. // - // Type: Snowflake + // Type: AppID AuditChannelApplicationID AuditLogChangeKey = "application_id" // AuditChannelRateLimitPerUser gets sent if the amount of seconds a user // has to wait before sending another message changed. @@ -342,12 +342,12 @@ const ( // AuditInviteChannelID gets sent if the channel for an invite code // changed. // - // Type: Snowflake + // Type: ChannelID AuditInviteChannelID AuditLogChangeKey = "channel_id" // AuditInviteInviterID specifies the person who created invite code // changed. // - // Type: Snowflake + // Type: UserID AuditInviteInviterID AuditLogChangeKey = "inviter_id" // AuditInviteMaxUses specifies the change to max number of times invite // code can be used. diff --git a/discord/channel.go b/discord/channel.go index 58c5c65..5ec3403 100644 --- a/discord/channel.go +++ b/discord/channel.go @@ -3,11 +3,11 @@ package discord // https://discord.com/developers/docs/resources/channel#channel-object type Channel struct { // ID is the id of this channel. - ID Snowflake `json:"id,string"` + ID ChannelID `json:"id,string"` // Type is the type of channel. Type ChannelType `json:"type"` // GuildID is the id of the guild. - GuildID Snowflake `json:"guild_id,string,omitempty"` + GuildID GuildID `json:"guild_id,string,omitempty"` // Position is the sorting position of the channel. Position int `json:"position,omitempty"` @@ -23,7 +23,7 @@ type Channel struct { // LastMessageID is the id of the last message sent in this channel (may // not point to an existing or valid message). - LastMessageID Snowflake `json:"last_message_id,string,omitempty"` + LastMessageID MessageID `json:"last_message_id,string,omitempty"` // VoiceBitrate is the bitrate (in bits) of the voice channel. VoiceBitrate uint `json:"bitrate,omitempty"` @@ -40,15 +40,15 @@ type Channel struct { // Icon is the icon hash. Icon Hash `json:"icon,omitempty"` // DMOwnerID is the id of the DM creator. - DMOwnerID Snowflake `json:"owner_id,string,omitempty"` + DMOwnerID UserID `json:"owner_id,string,omitempty"` // AppID is the application id of the group DM creator if it is // bot-created. - AppID Snowflake `json:"application_id,string,omitempty"` + AppID AppID `json:"application_id,string,omitempty"` // CategoryID is the id of the parent category for a channel (each parent // category can contain up to 50 channels). - CategoryID Snowflake `json:"parent_id,string,omitempty"` + CategoryID ChannelID `json:"parent_id,string,omitempty"` // LastPinTime is when the last pinned message was pinned. LastPinTime Timestamp `json:"last_pin_timestamp,omitempty"` } diff --git a/discord/emoji.go b/discord/emoji.go index a5d92fe..71a5795 100644 --- a/discord/emoji.go +++ b/discord/emoji.go @@ -3,13 +3,13 @@ package discord import "strings" type Emoji struct { - ID Snowflake `json:"id,string"` // NullSnowflake for unicode emojis - Name string `json:"name"` + ID EmojiID `json:"id,string"` // NullSnowflake for unicode emojis + Name string `json:"name"` // These fields are optional - RoleIDs []Snowflake `json:"roles,omitempty"` - User User `json:"user,omitempty"` + RoleIDs []RoleID `json:"roles,omitempty"` + User User `json:"user,omitempty"` RequireColons bool `json:"require_colons,omitempty"` Managed bool `json:"managed,omitempty"` @@ -33,7 +33,7 @@ func (e Emoji) EmojiURL() string { // // Supported ImageTypes: PNG, GIF func (e Emoji) EmojiURLWithType(t ImageType) string { - if e.ID == NullSnowflake { + if e.ID.IsNull() { return "" } diff --git a/discord/guild.go b/discord/guild.go index aafd190..3c33974 100644 --- a/discord/guild.go +++ b/discord/guild.go @@ -3,7 +3,7 @@ package discord // https://discord.com/developers/docs/resources/guild#guild-object type Guild struct { // ID is the guild id. - ID Snowflake `json:"id,string"` + ID GuildID `json:"id,string"` // Name is the guild name (2-100 characters, excluding trailing and leading // whitespace). Name string `json:"name"` @@ -19,7 +19,7 @@ type Guild struct { // Owner is true if the user is the owner of the guild. Owner bool `json:"owner,omitempty"` // OwnerID is the id of owner. - OwnerID Snowflake `json:"owner_id,string"` + OwnerID UserID `json:"owner_id,string"` // Permissions are the total permissions for the user in the guild // (excludes overrides). @@ -29,7 +29,7 @@ type Guild struct { VoiceRegion string `json:"region"` // AFKChannelID is the id of the afk channel. - AFKChannelID Snowflake `json:"afk_channel_id,string,omitempty"` + AFKChannelID ChannelID `json:"afk_channel_id,string,omitempty"` // AFKTimeout is the afk timeout in seconds. AFKTimeout Seconds `json:"afk_timeout"` @@ -41,7 +41,7 @@ type Guild struct { // to, or null if set to no invite . // // Deprecated: replaced with WidgetChannelID - EmbedChannelID Snowflake `json:"embed_channel_id,string,omitempty"` + EmbedChannelID ChannelID `json:"embed_channel_id,string,omitempty"` // Verification is the verification level required for the guild. Verification Verification `json:"verification_level"` @@ -63,23 +63,23 @@ type Guild struct { // AppID is the application id of the guild creator if it is bot-created. // // This field is nullable. - AppID Snowflake `json:"application_id,string,omitempty"` + AppID AppID `json:"application_id,string,omitempty"` // Widget is true if the server widget is enabled. Widget bool `json:"widget_enabled,omitempty"` // WidgetChannelID is the channel id that the widget will generate an // invite to, or null if set to no invite. - WidgetChannelID Snowflake `json:"widget_channel_id,string,omitempty"` + WidgetChannelID ChannelID `json:"widget_channel_id,string,omitempty"` // SystemChannelID is the the id of the channel where guild notices such as // welcome messages and boost events are posted. - SystemChannelID Snowflake `json:"system_channel_id,string,omitempty"` + SystemChannelID ChannelID `json:"system_channel_id,string,omitempty"` // SystemChannelFlags are the system channel flags. SystemChannelFlags SystemChannelFlags `json:"system_channel_flags"` // RulesChannelID is the id of the channel where guilds with the "PUBLIC" // feature can display rules and/or guidelines. - RulesChannelID Snowflake `json:"rules_channel_id"` + RulesChannelID ChannelID `json:"rules_channel_id"` // MaxPresences is the maximum number of presences for the guild (the // default value, currently 25000, is in effect when null is returned, so @@ -110,7 +110,7 @@ type Guild struct { // PublicUpdatesChannelID is the id of the channel where admins and // moderators of guilds with the "PUBLIC" feature receive notices from // Discord. - PublicUpdatesChannelID Snowflake `json:"public_updates_channel_id"` + PublicUpdatesChannelID ChannelID `json:"public_updates_channel_id"` // MaxVideoChannelUsers is the maximum amount of users in a video channel. MaxVideoChannelUsers uint64 `json:"max_video_channel_users,omitempty"` @@ -200,7 +200,7 @@ func (g Guild) DiscoverySplashURLWithType(t ImageType) string { // https://discord.com/developers/docs/resources/guild#guild-preview-object type GuildPreview struct { // ID is the guild id. - ID Snowflake `json:"id"` + ID GuildID `json:"id"` // Name is the guild name (2-100 characters). Name string `json:"name"` @@ -285,7 +285,7 @@ func (g GuildPreview) DiscoverySplashURLWithType(t ImageType) string { // https://discord.com/developers/docs/topics/permissions#role-object type Role struct { // ID is the role id. - ID Snowflake `json:"id,string"` + ID RoleID `json:"id,string"` // Name is the role name. Name string `json:"name"` @@ -315,7 +315,7 @@ type Presence struct { // User is the user presence is being updated for. User User `json:"user"` // RoleIDs are the roles this user is in. - RoleIDs []Snowflake `json:"roles"` + RoleIDs []RoleID `json:"roles"` // These fields are only filled in gateway events, according to the // documentation. @@ -324,7 +324,7 @@ type Presence struct { Game *Activity `json:"game"` // GuildID is the id of the guild - GuildID Snowflake `json:"guild_id"` + GuildID GuildID `json:"guild_id"` // Status is either "idle", "dnd", "online", or "offline". Status Status `json:"status"` @@ -360,7 +360,7 @@ type Member struct { // Nick is this users guild nickname. Nick string `json:"nick,omitempty"` // RoleIDs is an array of role object ids. - RoleIDs []Snowflake `json:"roles"` + RoleIDs []RoleID `json:"roles"` // Joined specifies when the user joined the guild. Joined Timestamp `json:"joined_at"` @@ -389,7 +389,7 @@ type Ban struct { // https://discord.com/developers/docs/resources/guild#integration-object type Integration struct { // ID is the integration id. - ID Snowflake `json:"id"` + ID IntegrationID `json:"id"` // Name is the integration name. Name string `json:"name"` // Type is the integration type (twitch, youtube, etc). @@ -401,7 +401,7 @@ type Integration struct { Syncing bool `json:"syncing"` // RoleID is the id that this integration uses for "subscribers". - RoleID Snowflake `json:"role_id"` + RoleID RoleID `json:"role_id"` // EnableEmoticons specifies whether emoticons should be synced for this // integration (twitch only currently). @@ -434,7 +434,7 @@ type GuildWidget struct { // Enabled specifies whether the widget is enabled. Enabled bool `json:"enabled"` // ChannelID is the widget channel id. - ChannelID Snowflake `json:"channel_id,omitempty"` + ChannelID ChannelID `json:"channel_id,omitempty"` } // DefaultMemberColor is the color used for members without colored roles. diff --git a/discord/message.go b/discord/message.go index 6adb0ef..4b55cec 100644 --- a/discord/message.go +++ b/discord/message.go @@ -7,10 +7,10 @@ import ( ) type Message struct { - ID Snowflake `json:"id,string"` + ID MessageID `json:"id,string"` Type MessageType `json:"type"` - ChannelID Snowflake `json:"channel_id,string"` - GuildID Snowflake `json:"guild_id,string,omitempty"` + ChannelID ChannelID `json:"channel_id,string"` + GuildID GuildID `json:"guild_id,string,omitempty"` // The author object follows the structure of the user object, but is only // a valid user in the case where the message is generated by a user or bot @@ -33,8 +33,8 @@ type Message struct { // text-based guild channels. Mentions []GuildUser `json:"mentions"` - MentionRoleIDs []Snowflake `json:"mention_roles"` - MentionEveryone bool `json:"mention_everyone"` + MentionRoleIDs []RoleID `json:"mention_roles"` + MentionEveryone bool `json:"mention_everyone"` // Not all channel mentions in a message will appear in mention_channels. MentionChannels []ChannelMention `json:"mention_channels,omitempty"` @@ -47,7 +47,7 @@ type Message struct { // Used for validating a message was sent Nonce string `json:"nonce,omitempty"` - WebhookID Snowflake `json:"webhook_id,string,omitempty"` + WebhookID WebhookID `json:"webhook_id,string,omitempty"` Activity *MessageActivity `json:"activity,omitempty"` Application *MessageApplication `json:"application,omitempty"` Reference *MessageReference `json:"message_reference,omitempty"` @@ -100,8 +100,8 @@ var ( ) type ChannelMention struct { - ChannelID Snowflake `json:"id,string"` - GuildID Snowflake `json:"guild_id,string"` + ChannelID ChannelID `json:"id,string"` + GuildID GuildID `json:"guild_id,string"` ChannelType ChannelType `json:"type"` ChannelName string `json:"name"` } @@ -132,29 +132,29 @@ const ( // type MessageApplication struct { - ID Snowflake `json:"id,string"` - CoverID string `json:"cover_image,omitempty"` - Description string `json:"description"` - Icon string `json:"icon"` - Name string `json:"name"` + ID AppID `json:"id,string"` + CoverID string `json:"cover_image,omitempty"` + Description string `json:"description"` + Icon string `json:"icon"` + Name string `json:"name"` } // type MessageReference struct { - ChannelID Snowflake `json:"channel_id,string"` + ChannelID ChannelID `json:"channel_id,string"` // Field might not be provided - MessageID Snowflake `json:"message_id,string,omitempty"` - GuildID Snowflake `json:"guild_id,string,omitempty"` + MessageID MessageID `json:"message_id,string,omitempty"` + GuildID GuildID `json:"guild_id,string,omitempty"` } // type Attachment struct { - ID Snowflake `json:"id,string"` - Filename string `json:"filename"` - Size uint64 `json:"size"` + ID AttachmentID `json:"id,string"` + Filename string `json:"filename"` + Size uint64 `json:"size"` URL URL `json:"url"` Proxy URL `json:"proxy_url"` diff --git a/discord/permission.go b/discord/permission.go index 18e4426..6444a66 100644 --- a/discord/permission.go +++ b/discord/permission.go @@ -126,7 +126,7 @@ func CalcOverwrites(guild Guild, channel Channel, member Member) Permissions { var perm Permissions for _, role := range guild.Roles { - if role.ID == guild.ID { + if role.ID == RoleID(guild.ID) { perm |= role.Permissions break } @@ -146,7 +146,7 @@ func CalcOverwrites(guild Guild, channel Channel, member Member) Permissions { } for _, overwrite := range channel.Permissions { - if overwrite.ID == guild.ID { + if GuildID(overwrite.ID) == guild.ID { perm &= ^overwrite.Deny perm |= overwrite.Allow break @@ -157,7 +157,7 @@ func CalcOverwrites(guild Guild, channel Channel, member Member) Permissions { for _, overwrite := range channel.Permissions { for _, id := range member.RoleIDs { - if id == overwrite.ID && overwrite.Type == "role" { + if id == RoleID(overwrite.ID) && overwrite.Type == "role" { deny |= overwrite.Deny allow |= overwrite.Allow break @@ -169,7 +169,7 @@ func CalcOverwrites(guild Guild, channel Channel, member Member) Permissions { perm |= allow for _, overwrite := range channel.Permissions { - if overwrite.ID == member.User.ID { + if UserID(overwrite.ID) == member.User.ID { perm &= ^overwrite.Deny perm |= overwrite.Allow break diff --git a/discord/snowflake.go b/discord/snowflake.go index cc00948..1661a37 100644 --- a/discord/snowflake.go +++ b/discord/snowflake.go @@ -73,6 +73,11 @@ func (s Snowflake) Valid() bool { return int64(s) > 0 } +// IsNull returns whether or not the snowflake is null. +func (s Snowflake) IsNull() bool { + return s == NullSnowflake +} + func (s Snowflake) Time() time.Time { unixnano := ((time.Duration(s) >> 22) * time.Millisecond) + DiscordEpoch return time.Unix(0, int64(unixnano)) @@ -89,3 +94,135 @@ func (s Snowflake) PID() uint8 { func (s Snowflake) Increment() uint16 { return uint16(s & 0xFFF) } + +type AppID Snowflake + +func (s AppID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *AppID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s AppID) String() string { return Snowflake(s).String() } +func (s AppID) Valid() bool { return Snowflake(s).Valid() } +func (s AppID) IsNull() bool { return Snowflake(s).IsNull() } +func (s AppID) Time() time.Time { return Snowflake(s).Time() } +func (s AppID) Worker() uint8 { return Snowflake(s).Worker() } +func (s AppID) PID() uint8 { return Snowflake(s).PID() } +func (s AppID) Increment() uint16 { return Snowflake(s).Increment() } + +type AttachmentID Snowflake + +func (s AttachmentID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *AttachmentID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s AttachmentID) String() string { return Snowflake(s).String() } +func (s AttachmentID) Valid() bool { return Snowflake(s).Valid() } +func (s AttachmentID) IsNull() bool { return Snowflake(s).IsNull() } +func (s AttachmentID) Time() time.Time { return Snowflake(s).Time() } +func (s AttachmentID) Worker() uint8 { return Snowflake(s).Worker() } +func (s AttachmentID) PID() uint8 { return Snowflake(s).PID() } +func (s AttachmentID) Increment() uint16 { return Snowflake(s).Increment() } + +type AuditLogEntryID Snowflake + +func (s AuditLogEntryID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *AuditLogEntryID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s AuditLogEntryID) String() string { return Snowflake(s).String() } +func (s AuditLogEntryID) Valid() bool { return Snowflake(s).Valid() } +func (s AuditLogEntryID) IsNull() bool { return Snowflake(s).IsNull() } +func (s AuditLogEntryID) Time() time.Time { return Snowflake(s).Time() } +func (s AuditLogEntryID) Worker() uint8 { return Snowflake(s).Worker() } +func (s AuditLogEntryID) PID() uint8 { return Snowflake(s).PID() } +func (s AuditLogEntryID) Increment() uint16 { return Snowflake(s).Increment() } + +type ChannelID Snowflake + +func (s ChannelID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *ChannelID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s ChannelID) String() string { return Snowflake(s).String() } +func (s ChannelID) Valid() bool { return Snowflake(s).Valid() } +func (s ChannelID) IsNull() bool { return Snowflake(s).IsNull() } +func (s ChannelID) Time() time.Time { return Snowflake(s).Time() } +func (s ChannelID) Worker() uint8 { return Snowflake(s).Worker() } +func (s ChannelID) PID() uint8 { return Snowflake(s).PID() } +func (s ChannelID) Increment() uint16 { return Snowflake(s).Increment() } + +type EmojiID Snowflake + +func (s EmojiID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *EmojiID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s EmojiID) String() string { return Snowflake(s).String() } +func (s EmojiID) Valid() bool { return Snowflake(s).Valid() } +func (s EmojiID) IsNull() bool { return Snowflake(s).IsNull() } +func (s EmojiID) Time() time.Time { return Snowflake(s).Time() } +func (s EmojiID) Worker() uint8 { return Snowflake(s).Worker() } +func (s EmojiID) PID() uint8 { return Snowflake(s).PID() } +func (s EmojiID) Increment() uint16 { return Snowflake(s).Increment() } + +type IntegrationID Snowflake + +func (s IntegrationID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *IntegrationID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s IntegrationID) String() string { return Snowflake(s).String() } +func (s IntegrationID) Valid() bool { return Snowflake(s).Valid() } +func (s IntegrationID) IsNull() bool { return Snowflake(s).IsNull() } +func (s IntegrationID) Time() time.Time { return Snowflake(s).Time() } +func (s IntegrationID) Worker() uint8 { return Snowflake(s).Worker() } +func (s IntegrationID) PID() uint8 { return Snowflake(s).PID() } +func (s IntegrationID) Increment() uint16 { return Snowflake(s).Increment() } + +type GuildID Snowflake + +func (s GuildID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *GuildID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s GuildID) String() string { return Snowflake(s).String() } +func (s GuildID) Valid() bool { return Snowflake(s).Valid() } +func (s GuildID) IsNull() bool { return Snowflake(s).IsNull() } +func (s GuildID) Time() time.Time { return Snowflake(s).Time() } +func (s GuildID) Worker() uint8 { return Snowflake(s).Worker() } +func (s GuildID) PID() uint8 { return Snowflake(s).PID() } +func (s GuildID) Increment() uint16 { return Snowflake(s).Increment() } + +type MessageID Snowflake + +func (s MessageID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *MessageID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s MessageID) String() string { return Snowflake(s).String() } +func (s MessageID) Valid() bool { return Snowflake(s).Valid() } +func (s MessageID) IsNull() bool { return Snowflake(s).IsNull() } +func (s MessageID) Time() time.Time { return Snowflake(s).Time() } +func (s MessageID) Worker() uint8 { return Snowflake(s).Worker() } +func (s MessageID) PID() uint8 { return Snowflake(s).PID() } +func (s MessageID) Increment() uint16 { return Snowflake(s).Increment() } + +type RoleID Snowflake + +func (s RoleID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *RoleID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s RoleID) String() string { return Snowflake(s).String() } +func (s RoleID) Valid() bool { return Snowflake(s).Valid() } +func (s RoleID) IsNull() bool { return Snowflake(s).IsNull() } +func (s RoleID) Time() time.Time { return Snowflake(s).Time() } +func (s RoleID) Worker() uint8 { return Snowflake(s).Worker() } +func (s RoleID) PID() uint8 { return Snowflake(s).PID() } +func (s RoleID) Increment() uint16 { return Snowflake(s).Increment() } + +type UserID Snowflake + +func (s UserID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *UserID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s UserID) String() string { return Snowflake(s).String() } +func (s UserID) Valid() bool { return Snowflake(s).Valid() } +func (s UserID) IsNull() bool { return Snowflake(s).IsNull() } +func (s UserID) Time() time.Time { return Snowflake(s).Time() } +func (s UserID) Worker() uint8 { return Snowflake(s).Worker() } +func (s UserID) PID() uint8 { return Snowflake(s).PID() } +func (s UserID) Increment() uint16 { return Snowflake(s).Increment() } + +type WebhookID Snowflake + +func (s WebhookID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *WebhookID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } +func (s WebhookID) String() string { return Snowflake(s).String() } +func (s WebhookID) Valid() bool { return Snowflake(s).Valid() } +func (s WebhookID) IsNull() bool { return Snowflake(s).IsNull() } +func (s WebhookID) Time() time.Time { return Snowflake(s).Time() } +func (s WebhookID) Worker() uint8 { return Snowflake(s).Worker() } +func (s WebhookID) PID() uint8 { return Snowflake(s).PID() } +func (s WebhookID) Increment() uint16 { return Snowflake(s).Increment() } diff --git a/discord/user.go b/discord/user.go index a0abaf0..e7076af 100644 --- a/discord/user.go +++ b/discord/user.go @@ -5,10 +5,10 @@ import ( ) type User struct { - ID Snowflake `json:"id,string"` - Username string `json:"username"` - Discriminator string `json:"discriminator"` - Avatar Hash `json:"avatar"` + ID UserID `json:"id,string"` + Username string `json:"username"` + Discriminator string `json:"discriminator"` + Avatar Hash `json:"avatar"` // These fields may be omitted @@ -93,9 +93,9 @@ const ( ) type Connection struct { - ID Snowflake `json:"id"` - Name string `json:"name"` - Type Service `json:"type"` + ID string `json:"id"` + Name string `json:"name"` + Type Service `json:"type"` Revoked bool `json:"revoked"` Verified bool `json:"verified"` @@ -136,10 +136,10 @@ type Activity struct { CreatedAt UnixTimestamp `json:"created_at,omitempty"` Timestamps *ActivityTimestamp `json:"timestamps,omitempty"` - ApplicationID Snowflake `json:"application_id,omitempty"` - Details string `json:"details,omitempty"` - State string `json:"state,omitempty"` // party status - Emoji *Emoji `json:"emoji,omitempty"` + ApplicationID AppID `json:"application_id,omitempty"` + Details string `json:"details,omitempty"` + State string `json:"state,omitempty"` // party status + Emoji *Emoji `json:"emoji,omitempty"` Party *ActivityParty `json:"party,omitempty"` Assets *ActivityAssets `json:"assets,omitempty"` @@ -204,7 +204,7 @@ type ActivitySecrets struct { // A Relationship between the logged in user and the user in the struct. This // struct is undocumented. type Relationship struct { - UserID Snowflake `json:"id"` + UserID UserID `json:"id"` User User `json:"user"` Type RelationshipType `json:"type"` } diff --git a/discord/voice.go b/discord/voice.go index d3beefc..2561b41 100644 --- a/discord/voice.go +++ b/discord/voice.go @@ -2,10 +2,10 @@ package discord type VoiceState struct { // GuildID isn't available from the Guild struct. - GuildID Snowflake `json:"guild_id,string"` + GuildID GuildID `json:"guild_id,string"` - ChannelID Snowflake `json:"channel_id,string"` - UserID Snowflake `json:"user_id,string"` + ChannelID ChannelID `json:"channel_id,string"` + UserID UserID `json:"user_id,string"` Member *Member `json:"member,omitempty"` SessionID string `json:"session_id"` diff --git a/discord/webhook.go b/discord/webhook.go index 1f03f36..192b3a5 100644 --- a/discord/webhook.go +++ b/discord/webhook.go @@ -1,12 +1,12 @@ package discord type Webhook struct { - ID Snowflake `json:"id"` + ID WebhookID `json:"id"` Type WebhookType `json:"type"` User User `json:"user"` // creator - GuildID Snowflake `json:"guild_id,omitempty"` - ChannelID Snowflake `json:"channel_id"` + GuildID GuildID `json:"guild_id,omitempty"` + ChannelID ChannelID `json:"channel_id"` Name string `json:"name"` Avatar Hash `json:"avatar"` diff --git a/gateway/commands.go b/gateway/commands.go index e95697a..6fe37ed 100644 --- a/gateway/commands.go +++ b/gateway/commands.go @@ -78,8 +78,8 @@ func (g *Gateway) HeartbeatCtx(ctx context.Context) error { } type RequestGuildMembersData struct { - GuildID []discord.Snowflake `json:"guild_id"` - UserIDs []discord.Snowflake `json:"user_ids,omitempty"` + GuildID []discord.GuildID `json:"guild_id"` + UserIDs []discord.UserID `json:"user_ids,omitempty"` Query string `json:"query,omitempty"` Limit uint `json:"limit"` @@ -101,8 +101,8 @@ func (g *Gateway) RequestGuildMembersCtx( } type UpdateVoiceStateData struct { - GuildID discord.Snowflake `json:"guild_id"` - ChannelID discord.Snowflake `json:"channel_id"` // nullable + GuildID discord.GuildID `json:"guild_id"` + ChannelID discord.ChannelID `json:"channel_id"` // nullable SelfMute bool `json:"self_mute"` SelfDeaf bool `json:"self_deaf"` } @@ -144,12 +144,12 @@ func (g *Gateway) UpdateStatusCtx(ctx context.Context, data UpdateStatusData) er // Undocumented type GuildSubscribeData struct { - Typing bool `json:"typing"` - Activities bool `json:"activities"` - GuildID discord.Snowflake `json:"guild_id"` + Typing bool `json:"typing"` + Activities bool `json:"activities"` + GuildID discord.GuildID `json:"guild_id"` // Channels is not documented. It's used to fetch the right members sidebar. - Channels map[discord.Snowflake][][2]int `json:"channels"` + Channels map[discord.ChannelID][][2]int `json:"channels"` } func (g *Gateway) GuildSubscribe(data GuildSubscribeData) error { diff --git a/gateway/events.go b/gateway/events.go index dec4d62..494aaa4 100644 --- a/gateway/events.go +++ b/gateway/events.go @@ -30,17 +30,17 @@ type ( discord.Channel } ChannelPinsUpdateEvent struct { - GuildID discord.Snowflake `json:"guild_id,omitempty"` - ChannelID discord.Snowflake `json:"channel_id,omitempty"` + GuildID discord.GuildID `json:"guild_id,omitempty"` + ChannelID discord.ChannelID `json:"channel_id,omitempty"` LastPin discord.Timestamp `json:"timestamp,omitempty"` } ChannelUnreadUpdateEvent struct { - GuildID discord.Snowflake `json:"guild_id"` + GuildID discord.GuildID `json:"guild_id"` ChannelUnreadUpdates []struct { - ID discord.Snowflake `json:"id"` - LastMessageID discord.Snowflake `json:"last_message_id"` + ID discord.ChannelID `json:"id"` + LastMessageID discord.MessageID `json:"last_message_id"` } } ) @@ -64,48 +64,48 @@ type ( discord.Guild } GuildDeleteEvent struct { - ID discord.Snowflake `json:"id"` + ID discord.GuildID `json:"id"` // Unavailable if false == removed Unavailable bool `json:"unavailable"` } GuildBanAddEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - User discord.User `json:"user"` + GuildID discord.GuildID `json:"guild_id"` + User discord.User `json:"user"` } GuildBanRemoveEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - User discord.User `json:"user"` + GuildID discord.GuildID `json:"guild_id"` + User discord.User `json:"user"` } GuildEmojisUpdateEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - Emojis []discord.Emoji `json:"emoji"` + GuildID discord.GuildID `json:"guild_id"` + Emojis []discord.Emoji `json:"emoji"` } GuildIntegrationsUpdateEvent struct { - GuildID discord.Snowflake `json:"guild_id"` + GuildID discord.GuildID `json:"guild_id"` } GuildMemberAddEvent struct { discord.Member - GuildID discord.Snowflake `json:"guild_id"` + GuildID discord.GuildID `json:"guild_id"` } GuildMemberRemoveEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - User discord.User `json:"user"` + GuildID discord.GuildID `json:"guild_id"` + User discord.User `json:"user"` } GuildMemberUpdateEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - RoleIDs []discord.Snowflake `json:"roles"` - User discord.User `json:"user"` - Nick string `json:"nick"` + GuildID discord.GuildID `json:"guild_id"` + RoleIDs []discord.RoleID `json:"roles"` + User discord.User `json:"user"` + Nick string `json:"nick"` } // GuildMembersChunkEvent is sent when Guild Request Members is called. GuildMembersChunkEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - Members []discord.Member `json:"members"` + GuildID discord.GuildID `json:"guild_id"` + Members []discord.Member `json:"members"` ChunkIndex int `json:"chunk_index"` ChunkCount int `json:"chunk_count"` @@ -122,10 +122,10 @@ type ( // client sends over GuildSubscriptions with the Channels field used. // The State package does not handle this event. GuildMemberListUpdate struct { - ID string `json:"id"` - GuildID discord.Snowflake `json:"guild_id"` - MemberCount uint64 `json:"member_count"` - OnlineCount uint64 `json:"online_count"` + ID string `json:"id"` + GuildID discord.GuildID `json:"guild_id"` + MemberCount uint64 `json:"member_count"` + OnlineCount uint64 `json:"online_count"` // Groups is all the visible role sections. Groups []GuildMemberListGroup `json:"groups"` @@ -133,7 +133,7 @@ type ( Ops []GuildMemberListOp `json:"ops"` } GuildMemberListGroup struct { - ID string `json:"id"` // either discord.Snowflake Role IDs or "online" + ID string `json:"id"` // either discord.RoleID or "online" Count uint64 `json:"count"` } GuildMemberListOp struct { @@ -164,16 +164,16 @@ type ( } GuildRoleCreateEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - Role discord.Role `json:"role"` + GuildID discord.GuildID `json:"guild_id"` + Role discord.Role `json:"role"` } GuildRoleUpdateEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - Role discord.Role `json:"role"` + GuildID discord.GuildID `json:"guild_id"` + Role discord.Role `json:"role"` } GuildRoleDeleteEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - RoleID discord.Snowflake `json:"role_id"` + GuildID discord.GuildID `json:"guild_id"` + RoleID discord.RoleID `json:"role_id"` } ) @@ -188,8 +188,8 @@ type ( InviteCreateEvent struct { Code string `json:"code"` CreatedAt discord.Timestamp `json:"created_at"` - ChannelID discord.Snowflake `json:"channel_id"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` + ChannelID discord.ChannelID `json:"channel_id"` + GuildID discord.GuildID `json:"guild_id,omitempty"` // Similar to discord.Invite Inviter *discord.User `json:"inviter,omitempty"` @@ -200,8 +200,8 @@ type ( } InviteDeleteEvent struct { Code string `json:"code"` - ChannelID discord.Snowflake `json:"channel_id"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` + ChannelID discord.ChannelID `json:"channel_id"` + GuildID discord.GuildID `json:"guild_id,omitempty"` } ) @@ -216,48 +216,48 @@ type ( Member *discord.Member `json:"member,omitempty"` } MessageDeleteEvent struct { - ID discord.Snowflake `json:"id"` - ChannelID discord.Snowflake `json:"channel_id"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` + ID discord.MessageID `json:"id"` + ChannelID discord.ChannelID `json:"channel_id"` + GuildID discord.GuildID `json:"guild_id,omitempty"` } MessageDeleteBulkEvent struct { - IDs []discord.Snowflake `json:"ids"` - ChannelID discord.Snowflake `json:"channel_id"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` + IDs []discord.MessageID `json:"ids"` + ChannelID discord.ChannelID `json:"channel_id"` + GuildID discord.GuildID `json:"guild_id,omitempty"` } MessageReactionAddEvent struct { - UserID discord.Snowflake `json:"user_id"` - ChannelID discord.Snowflake `json:"channel_id"` - MessageID discord.Snowflake `json:"message_id"` + UserID discord.UserID `json:"user_id"` + ChannelID discord.ChannelID `json:"channel_id"` + MessageID discord.MessageID `json:"message_id"` Emoji discord.Emoji `json:"emoji,omitempty"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` - Member *discord.Member `json:"member,omitempty"` + GuildID discord.GuildID `json:"guild_id,omitempty"` + Member *discord.Member `json:"member,omitempty"` } MessageReactionRemoveEvent struct { - UserID discord.Snowflake `json:"user_id"` - ChannelID discord.Snowflake `json:"channel_id"` - MessageID discord.Snowflake `json:"message_id"` + UserID discord.UserID `json:"user_id"` + ChannelID discord.ChannelID `json:"channel_id"` + MessageID discord.MessageID `json:"message_id"` Emoji discord.Emoji `json:"emoji"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` + GuildID discord.GuildID `json:"guild_id,omitempty"` } MessageReactionRemoveAllEvent struct { - ChannelID discord.Snowflake `json:"channel_id"` - MessageID discord.Snowflake `json:"message_id"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` + ChannelID discord.ChannelID `json:"channel_id"` + MessageID discord.MessageID `json:"message_id"` + GuildID discord.GuildID `json:"guild_id,omitempty"` } MessageReactionRemoveEmoji struct { - ChannelID discord.Snowflake `json:"channel_id"` - MessageID discord.Snowflake `json:"message_id"` + ChannelID discord.ChannelID `json:"channel_id"` + MessageID discord.MessageID `json:"message_id"` Emoji discord.Emoji `json:"emoji"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` + GuildID discord.GuildID `json:"guild_id,omitempty"` } MessageAckEvent struct { - MessageID discord.Snowflake `json:"message_id"` - ChannelID discord.Snowflake `json:"channel_id"` + MessageID discord.MessageID `json:"message_id"` + ChannelID discord.ChannelID `json:"channel_id"` } ) @@ -288,12 +288,12 @@ type ( } TypingStartEvent struct { - ChannelID discord.Snowflake `json:"channel_id"` - UserID discord.Snowflake `json:"user_id"` + ChannelID discord.ChannelID `json:"channel_id"` + UserID discord.UserID `json:"user_id"` Timestamp discord.UnixTimestamp `json:"timestamp"` - GuildID discord.Snowflake `json:"guild_id,omitempty"` - Member *discord.Member `json:"member,omitempty"` + GuildID discord.GuildID `json:"guild_id,omitempty"` + Member *discord.Member `json:"member,omitempty"` } UserUpdateEvent struct { @@ -307,17 +307,17 @@ type ( discord.VoiceState } VoiceServerUpdateEvent struct { - Token string `json:"token"` - GuildID discord.Snowflake `json:"guild_id"` - Endpoint string `json:"endpoint"` + Token string `json:"token"` + GuildID discord.GuildID `json:"guild_id"` + Endpoint string `json:"endpoint"` } ) // https://discordapp.com/developers/docs/topics/gateway#webhooks type ( WebhooksUpdateEvent struct { - GuildID discord.Snowflake `json:"guild_id"` - ChannelID discord.Snowflake `json:"channel_id"` + GuildID discord.GuildID `json:"guild_id"` + ChannelID discord.ChannelID `json:"channel_id"` } ) @@ -330,8 +330,8 @@ type ( UserSettings } UserNoteUpdateEvent struct { - ID discord.Snowflake `json:"id"` - Note string `json:"note"` + ID discord.UserID `json:"id"` + Note string `json:"note"` } ) diff --git a/gateway/ready.go b/gateway/ready.go index 5edca1b..9e6dc2f 100644 --- a/gateway/ready.go +++ b/gateway/ready.go @@ -20,8 +20,8 @@ type ReadyEvent struct { ReadState []ReadState `json:"read_state,omitempty"` Presences []discord.Presence `json:"presences,omitempty"` - Relationships []discord.Relationship `json:"relationships,omitempty"` - Notes map[discord.Snowflake]string `json:"notes,omitempty"` + Relationships []discord.Relationship `json:"relationships,omitempty"` + Notes map[discord.UserID]string `json:"notes,omitempty"` } type UserSettings struct { @@ -48,9 +48,9 @@ type UserSettings struct { Locale string `json:"locale"` Theme string `json:"theme"` - GuildPositions []discord.Snowflake `json:"guild_positions"` - GuildFolders []GuildFolder `json:"guild_folders"` - RestrictedGuilds []discord.Snowflake `json:"restricted_guilds"` + GuildPositions []discord.GuildID `json:"guild_positions"` + GuildFolders []GuildFolder `json:"guild_folders"` + RestrictedGuilds []discord.GuildID `json:"restricted_guilds"` FriendSourceFlags struct { All bool `json:"all"` @@ -62,14 +62,14 @@ type UserSettings struct { CustomStatus struct { Text string `json:"text"` ExpiresAt discord.Timestamp `json:"expires_at,omitempty"` - EmojiID discord.Snowflake `json:"emoji_id,string"` + EmojiID discord.EmojiID `json:"emoji_id,string"` EmojiName string `json:"emoji_name"` } `json:"custom_status"` } // A UserGuildSettings stores data for a users guild settings. type UserGuildSettings struct { - GuildID discord.Snowflake `json:"guild_id"` + GuildID discord.GuildID `json:"guild_id"` SupressEveryone bool `json:"suppress_everyone"` SupressRoles bool `json:"suppress_roles"` @@ -91,8 +91,8 @@ const ( ) type ReadState struct { - ChannelID discord.Snowflake `json:"id"` - LastMessageID discord.Snowflake `json:"last_message_id"` + ChannelID discord.ChannelID `json:"id"` + LastMessageID discord.MessageID `json:"last_message_id"` MentionCount int `json:"mention_count"` } @@ -102,13 +102,13 @@ type SettingsChannelOverride struct { Muted bool `json:"muted"` MessageNotifications UserNotification `json:"message_notifications"` - ChannelID discord.Snowflake `json:"channel_id"` + ChannelID discord.ChannelID `json:"channel_id"` } // GuildFolder holds a single folder that you see in the left guild panel. type GuildFolder struct { - Name string `json:"name"` - ID discord.Snowflake `json:"id"` - GuildIDs []discord.Snowflake `json:"guild_ids"` - Color discord.Color `json:"color"` + Name string `json:"name"` + ID string `json:"id"` + GuildIDs []discord.GuildID `json:"guild_ids"` + Color discord.Color `json:"color"` } diff --git a/state/state.go b/state/state.go index b1c2e1b..f363dd4 100644 --- a/state/state.go +++ b/state/state.go @@ -84,17 +84,17 @@ type State struct { // List of channels with few messages, so it doesn't bother hitting the API // again. - fewMessages map[discord.Snowflake]struct{} + fewMessages map[discord.ChannelID]struct{} fewMutex *sync.Mutex - // unavailableGuilds is a set of discord.Snowflakes of guilds that became + // unavailableGuilds is a set of discord.GuildIDs of guilds that became // unavailable when already connected to the gateway, i.e. sent in a // GuildUnavailableEvent. - unavailableGuilds *moreatomic.SnowflakeSet - // unreadyGuilds is a set of discord.Snowflakes of guilds that were + unavailableGuilds *moreatomic.GuildIDSet + // unreadyGuilds is a set of discord.GuildIDs of guilds that were // unavailable when connecting to the gateway, i.e. they had Unavailable // set to true during Ready. - unreadyGuilds *moreatomic.SnowflakeSet + unreadyGuilds *moreatomic.GuildIDSet } // New creates a new state. @@ -130,10 +130,10 @@ func NewFromSession(s *session.Session, store Store) (*State, error) { Store: store, Handler: handler.New(), StateLog: func(err error) {}, - fewMessages: map[discord.Snowflake]struct{}{}, + fewMessages: map[discord.ChannelID]struct{}{}, fewMutex: new(sync.Mutex), - unavailableGuilds: moreatomic.NewSnowflakeSet(), - unreadyGuilds: moreatomic.NewSnowflakeSet(), + unavailableGuilds: moreatomic.NewGuildIDSet(), + unreadyGuilds: moreatomic.NewGuildIDSet(), } state.hookSession() return state, nil @@ -171,7 +171,7 @@ func (s *State) AuthorDisplayName(message *gateway.MessageCreateEvent) string { return n } -func (s *State) MemberDisplayName(guildID, userID discord.Snowflake) (string, error) { +func (s *State) MemberDisplayName(guildID discord.GuildID, userID discord.UserID) (string, error) { member, err := s.Member(guildID, userID) if err != nil { return "", err @@ -200,7 +200,7 @@ func (s *State) AuthorColor(message *gateway.MessageCreateEvent) (discord.Color, return s.MemberColor(message.GuildID, message.Author.ID) } -func (s *State) MemberColor(guildID, userID discord.Snowflake) (discord.Color, error) { +func (s *State) MemberColor(guildID discord.GuildID, userID discord.UserID) (discord.Color, error) { var wg sync.WaitGroup g, gerr := s.Store.Guild(guildID) @@ -235,7 +235,7 @@ func (s *State) MemberColor(guildID, userID discord.Snowflake) (discord.Color, e //// -func (s *State) Permissions(channelID, userID discord.Snowflake) (discord.Permissions, error) { +func (s *State) Permissions(channelID discord.ChannelID, userID discord.UserID) (discord.Permissions, error) { ch, err := s.Channel(channelID) if err != nil { return 0, errors.Wrap(err, "failed to get channel") @@ -291,7 +291,7 @@ func (s *State) Me() (*discord.User, error) { //// -func (s *State) Channel(id discord.Snowflake) (*discord.Channel, error) { +func (s *State) Channel(id discord.ChannelID) (*discord.Channel, error) { c, err := s.Store.Channel(id) if err == nil { return c, nil @@ -305,7 +305,7 @@ func (s *State) Channel(id discord.Snowflake) (*discord.Channel, error) { return c, s.Store.ChannelSet(c) } -func (s *State) Channels(guildID discord.Snowflake) ([]discord.Channel, error) { +func (s *State) Channels(guildID discord.GuildID) ([]discord.Channel, error) { c, err := s.Store.Channels(guildID) if err == nil { return c, nil @@ -327,7 +327,7 @@ func (s *State) Channels(guildID discord.Snowflake) ([]discord.Channel, error) { return c, nil } -func (s *State) CreatePrivateChannel(recipient discord.Snowflake) (*discord.Channel, error) { +func (s *State) CreatePrivateChannel(recipient discord.UserID) (*discord.Channel, error) { c, err := s.Store.CreatePrivateChannel(recipient) if err == nil { return c, nil @@ -366,7 +366,7 @@ func (s *State) PrivateChannels() ([]discord.Channel, error) { //// func (s *State) Emoji( - guildID, emojiID discord.Snowflake) (*discord.Emoji, error) { + guildID discord.GuildID, emojiID discord.EmojiID) (*discord.Emoji, error) { e, err := s.Store.Emoji(guildID, emojiID) if err == nil { @@ -391,7 +391,7 @@ func (s *State) Emoji( return nil, ErrStoreNotFound } -func (s *State) Emojis(guildID discord.Snowflake) ([]discord.Emoji, error) { +func (s *State) Emojis(guildID discord.GuildID) ([]discord.Emoji, error) { e, err := s.Store.Emojis(guildID) if err == nil { return e, nil @@ -407,7 +407,7 @@ func (s *State) Emojis(guildID discord.Snowflake) ([]discord.Emoji, error) { //// -func (s *State) Guild(id discord.Snowflake) (*discord.Guild, error) { +func (s *State) Guild(id discord.GuildID) (*discord.Guild, error) { c, err := s.Store.Guild(id) if err == nil { return c, nil @@ -441,7 +441,7 @@ func (s *State) Guilds() ([]discord.Guild, error) { //// -func (s *State) Member(guildID, userID discord.Snowflake) (*discord.Member, error) { +func (s *State) Member(guildID discord.GuildID, userID discord.UserID) (*discord.Member, error) { m, err := s.Store.Member(guildID, userID) if err == nil { return m, nil @@ -450,7 +450,7 @@ func (s *State) Member(guildID, userID discord.Snowflake) (*discord.Member, erro return s.fetchMember(guildID, userID) } -func (s *State) Members(guildID discord.Snowflake) ([]discord.Member, error) { +func (s *State) Members(guildID discord.GuildID) ([]discord.Member, error) { ms, err := s.Store.Members(guildID) if err == nil { return ms, nil @@ -468,14 +468,14 @@ func (s *State) Members(guildID discord.Snowflake) ([]discord.Member, error) { } return ms, s.Gateway.RequestGuildMembers(gateway.RequestGuildMembersData{ - GuildID: []discord.Snowflake{guildID}, + GuildID: []discord.GuildID{guildID}, Presences: true, }) } //// -func (s *State) Message(channelID, messageID discord.Snowflake) (*discord.Message, error) { +func (s *State) Message(channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) { m, err := s.Store.Message(channelID, messageID) if err == nil { return m, nil @@ -515,7 +515,7 @@ func (s *State) Message(channelID, messageID discord.Snowflake) (*discord.Messag // Messages fetches maximum 100 messages from the API, if it has to. There is no // limit if it's from the State storage. -func (s *State) Messages(channelID discord.Snowflake) ([]discord.Message, error) { +func (s *State) Messages(channelID discord.ChannelID) ([]discord.Message, error) { // TODO: Think of a design that doesn't rely on MaxMessages(). var maxMsgs = s.MaxMessages() @@ -544,7 +544,7 @@ func (s *State) Messages(channelID discord.Snowflake) ([]discord.Message, error) // New messages fetched weirdly does not have GuildID filled. We'll try and // get it for consistency with incoming message creates. - var guildID discord.Snowflake + var guildID discord.GuildID // A bit too convoluted, but whatever. c, err := s.Channel(channelID) @@ -582,7 +582,7 @@ func (s *State) Messages(channelID discord.Snowflake) ([]discord.Message, error) // Presence checks the state for user presences. If no guildID is given, it will // look for the presence in all guilds. -func (s *State) Presence(guildID, userID discord.Snowflake) (*discord.Presence, error) { +func (s *State) Presence(guildID discord.GuildID, userID discord.UserID) (*discord.Presence, error) { p, err := s.Store.Presence(guildID, userID) if err == nil { return p, nil @@ -607,7 +607,7 @@ func (s *State) Presence(guildID, userID discord.Snowflake) (*discord.Presence, //// -func (s *State) Role(guildID, roleID discord.Snowflake) (*discord.Role, error) { +func (s *State) Role(guildID discord.GuildID, roleID discord.RoleID) (*discord.Role, error) { r, err := s.Store.Role(guildID, roleID) if err == nil { return r, nil @@ -635,7 +635,7 @@ func (s *State) Role(guildID, roleID discord.Snowflake) (*discord.Role, error) { return role, nil } -func (s *State) Roles(guildID discord.Snowflake) ([]discord.Role, error) { +func (s *State) Roles(guildID discord.GuildID) ([]discord.Role, error) { rs, err := s.Store.Roles(guildID) if err == nil { return rs, nil @@ -657,7 +657,7 @@ func (s *State) Roles(guildID discord.Snowflake) ([]discord.Role, error) { return rs, nil } -func (s *State) fetchGuild(id discord.Snowflake) (g *discord.Guild, err error) { +func (s *State) fetchGuild(id discord.GuildID) (g *discord.Guild, err error) { g, err = s.Session.Guild(id) if err == nil { err = s.Store.GuildSet(g) @@ -666,7 +666,7 @@ func (s *State) fetchGuild(id discord.Snowflake) (g *discord.Guild, err error) { return } -func (s *State) fetchMember(guildID, userID discord.Snowflake) (m *discord.Member, err error) { +func (s *State) fetchMember(guildID discord.GuildID, userID discord.UserID) (m *discord.Member, err error) { m, err = s.Session.Member(guildID, userID) if err == nil { err = s.Store.MemberSet(guildID, m) diff --git a/state/state_events.go b/state/state_events.go index caef14e..4a27bbe 100644 --- a/state/state_events.go +++ b/state/state_events.go @@ -308,7 +308,7 @@ func (s *State) batchLog(errors ...error) { // Helper functions -func (s *State) editMessage(ch, msg discord.Snowflake, fn func(m *discord.Message) bool) { +func (s *State) editMessage(ch discord.ChannelID, msg discord.MessageID, fn func(m *discord.Message) bool) { m, err := s.Store.Message(ch, msg) if err != nil { return diff --git a/state/store.go b/state/store.go index 3d1a533..4d4c91c 100644 --- a/state/store.go +++ b/state/store.go @@ -25,36 +25,36 @@ type StoreGetter interface { Me() (*discord.User, error) // Channel should check for both DM and guild channels. - Channel(id discord.Snowflake) (*discord.Channel, error) - Channels(guildID discord.Snowflake) ([]discord.Channel, error) + Channel(id discord.ChannelID) (*discord.Channel, error) + Channels(guildID discord.GuildID) ([]discord.Channel, error) // same API as (*api.Client) - CreatePrivateChannel(recipient discord.Snowflake) (*discord.Channel, error) + CreatePrivateChannel(recipient discord.UserID) (*discord.Channel, error) PrivateChannels() ([]discord.Channel, error) - Emoji(guildID, emojiID discord.Snowflake) (*discord.Emoji, error) - Emojis(guildID discord.Snowflake) ([]discord.Emoji, error) + Emoji(guildID discord.GuildID, emojiID discord.EmojiID) (*discord.Emoji, error) + Emojis(guildID discord.GuildID) ([]discord.Emoji, error) - Guild(id discord.Snowflake) (*discord.Guild, error) + Guild(id discord.GuildID) (*discord.Guild, error) Guilds() ([]discord.Guild, error) - Member(guildID, userID discord.Snowflake) (*discord.Member, error) - Members(guildID discord.Snowflake) ([]discord.Member, error) + Member(guildID discord.GuildID, userID discord.UserID) (*discord.Member, error) + Members(guildID discord.GuildID) ([]discord.Member, error) - Message(channelID, messageID discord.Snowflake) (*discord.Message, error) + Message(channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) // Messages should return messages ordered from latest to earliest. - Messages(channelID discord.Snowflake) ([]discord.Message, error) + Messages(channelID discord.ChannelID) ([]discord.Message, error) MaxMessages() int // used to know if the state is filled or not. // These don't get fetched from the API, it's Gateway only. - Presence(guildID, userID discord.Snowflake) (*discord.Presence, error) - Presences(guildID discord.Snowflake) ([]discord.Presence, error) + Presence(guildID discord.GuildID, userID discord.UserID) (*discord.Presence, error) + Presences(guildID discord.GuildID) ([]discord.Presence, error) - Role(guildID, roleID discord.Snowflake) (*discord.Role, error) - Roles(guildID discord.Snowflake) ([]discord.Role, error) + Role(guildID discord.GuildID, roleID discord.RoleID) (*discord.Role, error) + Roles(guildID discord.GuildID) ([]discord.Role, error) - VoiceState(guildID discord.Snowflake, userID discord.Snowflake) (*discord.VoiceState, error) - VoiceStates(guildID discord.Snowflake) ([]discord.VoiceState, error) + VoiceState(guildID discord.GuildID, userID discord.UserID) (*discord.VoiceState, error) + VoiceStates(guildID discord.GuildID) ([]discord.VoiceState, error) } type StoreModifier interface { @@ -66,27 +66,27 @@ type StoreModifier interface { ChannelRemove(*discord.Channel) error // EmojiSet should delete all old emojis before setting new ones. - EmojiSet(guildID discord.Snowflake, emojis []discord.Emoji) error + EmojiSet(guildID discord.GuildID, emojis []discord.Emoji) error GuildSet(*discord.Guild) error - GuildRemove(id discord.Snowflake) error + GuildRemove(id discord.GuildID) error - MemberSet(guildID discord.Snowflake, member *discord.Member) error - MemberRemove(guildID, userID discord.Snowflake) error + MemberSet(guildID discord.GuildID, member *discord.Member) error + MemberRemove(guildID discord.GuildID, userID discord.UserID) error // MessageSet should prepend messages into the slice, the latest being in // front. MessageSet(*discord.Message) error - MessageRemove(channelID, messageID discord.Snowflake) error + MessageRemove(channelID discord.ChannelID, messageID discord.MessageID) error - PresenceSet(guildID discord.Snowflake, presence *discord.Presence) error - PresenceRemove(guildID, userID discord.Snowflake) error + PresenceSet(guildID discord.GuildID, presence *discord.Presence) error + PresenceRemove(guildID discord.GuildID, userID discord.UserID) error - RoleSet(guildID discord.Snowflake, role *discord.Role) error - RoleRemove(guildID, roleID discord.Snowflake) error + RoleSet(guildID discord.GuildID, role *discord.Role) error + RoleRemove(guildID discord.GuildID, roleID discord.RoleID) error - VoiceStateSet(guildID discord.Snowflake, voiceState *discord.VoiceState) error - VoiceStateRemove(guildID discord.Snowflake, userID discord.Snowflake) error + VoiceStateSet(guildID discord.GuildID, voiceState *discord.VoiceState) error + VoiceStateRemove(guildID discord.GuildID, userID discord.UserID) error } // ErrStoreNotFound is an error that a store can use to return when something diff --git a/state/store_default.go b/state/store_default.go index 7fcb127..bdef92e 100644 --- a/state/store_default.go +++ b/state/store_default.go @@ -15,14 +15,14 @@ type DefaultStore struct { self discord.User // includes normal and private - privates map[discord.Snowflake]*discord.Channel // channelID:channel - guilds map[discord.Snowflake]*discord.Guild // guildID:guild + privates map[discord.ChannelID]*discord.Channel + guilds map[discord.GuildID]*discord.Guild - channels map[discord.Snowflake][]discord.Channel // guildID:channels - members map[discord.Snowflake][]discord.Member // guildID:members - presences map[discord.Snowflake][]discord.Presence // guildID:presences - messages map[discord.Snowflake][]discord.Message // channelID:messages - voiceStates map[discord.Snowflake][]discord.VoiceState // guildID:voiceStates + channels map[discord.GuildID][]discord.Channel + members map[discord.GuildID][]discord.Member + presences map[discord.GuildID][]discord.Presence + messages map[discord.ChannelID][]discord.Message + voiceStates map[discord.GuildID][]discord.VoiceState mut sync.Mutex } @@ -54,14 +54,14 @@ func (s *DefaultStore) Reset() error { s.self = discord.User{} - s.privates = map[discord.Snowflake]*discord.Channel{} - s.guilds = map[discord.Snowflake]*discord.Guild{} + s.privates = map[discord.ChannelID]*discord.Channel{} + s.guilds = map[discord.GuildID]*discord.Guild{} - s.channels = map[discord.Snowflake][]discord.Channel{} - s.members = map[discord.Snowflake][]discord.Member{} - s.presences = map[discord.Snowflake][]discord.Presence{} - s.messages = map[discord.Snowflake][]discord.Message{} - s.voiceStates = map[discord.Snowflake][]discord.VoiceState{} + s.channels = map[discord.GuildID][]discord.Channel{} + s.members = map[discord.GuildID][]discord.Member{} + s.presences = map[discord.GuildID][]discord.Presence{} + s.messages = map[discord.ChannelID][]discord.Message{} + s.voiceStates = map[discord.GuildID][]discord.VoiceState{} return nil } @@ -89,7 +89,7 @@ func (s *DefaultStore) MyselfSet(me *discord.User) error { //// -func (s *DefaultStore) Channel(id discord.Snowflake) (*discord.Channel, error) { +func (s *DefaultStore) Channel(id discord.ChannelID) (*discord.Channel, error) { s.mut.Lock() defer s.mut.Unlock() @@ -108,7 +108,7 @@ func (s *DefaultStore) Channel(id discord.Snowflake) (*discord.Channel, error) { return nil, ErrStoreNotFound } -func (s *DefaultStore) Channels(guildID discord.Snowflake) ([]discord.Channel, error) { +func (s *DefaultStore) Channels(guildID discord.GuildID) ([]discord.Channel, error) { s.mut.Lock() defer s.mut.Unlock() @@ -122,7 +122,7 @@ func (s *DefaultStore) Channels(guildID discord.Snowflake) ([]discord.Channel, e // CreatePrivateChannel searches in the cache for a private channel. It makes no // API calls. -func (s *DefaultStore) CreatePrivateChannel(recipient discord.Snowflake) (*discord.Channel, error) { +func (s *DefaultStore) CreatePrivateChannel(recipient discord.UserID) (*discord.Channel, error) { s.mut.Lock() defer s.mut.Unlock() @@ -205,7 +205,7 @@ func (s *DefaultStore) ChannelRemove(channel *discord.Channel) error { //// -func (s *DefaultStore) Emoji(guildID, emojiID discord.Snowflake) (*discord.Emoji, error) { +func (s *DefaultStore) Emoji(guildID discord.GuildID, emojiID discord.EmojiID) (*discord.Emoji, error) { s.mut.Lock() defer s.mut.Unlock() @@ -223,7 +223,7 @@ func (s *DefaultStore) Emoji(guildID, emojiID discord.Snowflake) (*discord.Emoji return nil, ErrStoreNotFound } -func (s *DefaultStore) Emojis(guildID discord.Snowflake) ([]discord.Emoji, error) { +func (s *DefaultStore) Emojis(guildID discord.GuildID) ([]discord.Emoji, error) { s.mut.Lock() defer s.mut.Unlock() @@ -235,7 +235,7 @@ func (s *DefaultStore) Emojis(guildID discord.Snowflake) ([]discord.Emoji, error return append([]discord.Emoji{}, gd.Emojis...), nil } -func (s *DefaultStore) EmojiSet(guildID discord.Snowflake, emojis []discord.Emoji) error { +func (s *DefaultStore) EmojiSet(guildID discord.GuildID, emojis []discord.Emoji) error { s.mut.Lock() defer s.mut.Unlock() @@ -269,7 +269,7 @@ Main: //// -func (s *DefaultStore) Guild(id discord.Snowflake) (*discord.Guild, error) { +func (s *DefaultStore) Guild(id discord.GuildID) (*discord.Guild, error) { s.mut.Lock() defer s.mut.Unlock() @@ -321,7 +321,7 @@ func (s *DefaultStore) GuildSet(guild *discord.Guild) error { return nil } -func (s *DefaultStore) GuildRemove(id discord.Snowflake) error { +func (s *DefaultStore) GuildRemove(id discord.GuildID) error { s.mut.Lock() delete(s.guilds, id) s.mut.Unlock() @@ -331,7 +331,7 @@ func (s *DefaultStore) GuildRemove(id discord.Snowflake) error { //// -func (s *DefaultStore) Member(guildID, userID discord.Snowflake) (*discord.Member, error) { +func (s *DefaultStore) Member(guildID discord.GuildID, userID discord.UserID) (*discord.Member, error) { s.mut.Lock() defer s.mut.Unlock() @@ -349,7 +349,7 @@ func (s *DefaultStore) Member(guildID, userID discord.Snowflake) (*discord.Membe return nil, ErrStoreNotFound } -func (s *DefaultStore) Members(guildID discord.Snowflake) ([]discord.Member, error) { +func (s *DefaultStore) Members(guildID discord.GuildID) ([]discord.Member, error) { s.mut.Lock() defer s.mut.Unlock() @@ -361,7 +361,7 @@ func (s *DefaultStore) Members(guildID discord.Snowflake) ([]discord.Member, err return append([]discord.Member{}, ms...), nil } -func (s *DefaultStore) MemberSet(guildID discord.Snowflake, member *discord.Member) error { +func (s *DefaultStore) MemberSet(guildID discord.GuildID, member *discord.Member) error { s.mut.Lock() defer s.mut.Unlock() @@ -385,7 +385,7 @@ func (s *DefaultStore) MemberSet(guildID discord.Snowflake, member *discord.Memb return nil } -func (s *DefaultStore) MemberRemove(guildID, userID discord.Snowflake) error { +func (s *DefaultStore) MemberRemove(guildID discord.GuildID, userID discord.UserID) error { s.mut.Lock() defer s.mut.Unlock() @@ -409,7 +409,7 @@ func (s *DefaultStore) MemberRemove(guildID, userID discord.Snowflake) error { //// -func (s *DefaultStore) Message(channelID, messageID discord.Snowflake) (*discord.Message, error) { +func (s *DefaultStore) Message(channelID discord.ChannelID, messageID discord.MessageID) (*discord.Message, error) { s.mut.Lock() defer s.mut.Unlock() @@ -427,7 +427,7 @@ func (s *DefaultStore) Message(channelID, messageID discord.Snowflake) (*discord return nil, ErrStoreNotFound } -func (s *DefaultStore) Messages(channelID discord.Snowflake) ([]discord.Message, error) { +func (s *DefaultStore) Messages(channelID discord.ChannelID) ([]discord.Message, error) { s.mut.Lock() defer s.mut.Unlock() @@ -486,7 +486,7 @@ func (s *DefaultStore) MessageSet(message *discord.Message) error { return nil } -func (s *DefaultStore) MessageRemove(channelID, messageID discord.Snowflake) error { +func (s *DefaultStore) MessageRemove(channelID discord.ChannelID, messageID discord.MessageID) error { s.mut.Lock() defer s.mut.Unlock() @@ -508,7 +508,7 @@ func (s *DefaultStore) MessageRemove(channelID, messageID discord.Snowflake) err //// -func (s *DefaultStore) Presence(guildID, userID discord.Snowflake) (*discord.Presence, error) { +func (s *DefaultStore) Presence(guildID discord.GuildID, userID discord.UserID) (*discord.Presence, error) { s.mut.Lock() defer s.mut.Unlock() @@ -526,7 +526,7 @@ func (s *DefaultStore) Presence(guildID, userID discord.Snowflake) (*discord.Pre return nil, ErrStoreNotFound } -func (s *DefaultStore) Presences(guildID discord.Snowflake) ([]discord.Presence, error) { +func (s *DefaultStore) Presences(guildID discord.GuildID) ([]discord.Presence, error) { s.mut.Lock() defer s.mut.Unlock() @@ -538,7 +538,7 @@ func (s *DefaultStore) Presences(guildID discord.Snowflake) ([]discord.Presence, return ps, nil } -func (s *DefaultStore) PresenceSet(guildID discord.Snowflake, presence *discord.Presence) error { +func (s *DefaultStore) PresenceSet(guildID discord.GuildID, presence *discord.Presence) error { s.mut.Lock() defer s.mut.Unlock() @@ -558,7 +558,7 @@ func (s *DefaultStore) PresenceSet(guildID discord.Snowflake, presence *discord. return nil } -func (s *DefaultStore) PresenceRemove(guildID, userID discord.Snowflake) error { +func (s *DefaultStore) PresenceRemove(guildID discord.GuildID, userID discord.UserID) error { s.mut.Lock() defer s.mut.Unlock() @@ -581,7 +581,7 @@ func (s *DefaultStore) PresenceRemove(guildID, userID discord.Snowflake) error { //// -func (s *DefaultStore) Role(guildID, roleID discord.Snowflake) (*discord.Role, error) { +func (s *DefaultStore) Role(guildID discord.GuildID, roleID discord.RoleID) (*discord.Role, error) { s.mut.Lock() defer s.mut.Unlock() @@ -599,7 +599,7 @@ func (s *DefaultStore) Role(guildID, roleID discord.Snowflake) (*discord.Role, e return nil, ErrStoreNotFound } -func (s *DefaultStore) Roles(guildID discord.Snowflake) ([]discord.Role, error) { +func (s *DefaultStore) Roles(guildID discord.GuildID) ([]discord.Role, error) { s.mut.Lock() defer s.mut.Unlock() @@ -611,7 +611,7 @@ func (s *DefaultStore) Roles(guildID discord.Snowflake) ([]discord.Role, error) return append([]discord.Role{}, gd.Roles...), nil } -func (s *DefaultStore) RoleSet(guildID discord.Snowflake, role *discord.Role) error { +func (s *DefaultStore) RoleSet(guildID discord.GuildID, role *discord.Role) error { s.mut.Lock() defer s.mut.Unlock() @@ -631,7 +631,7 @@ func (s *DefaultStore) RoleSet(guildID discord.Snowflake, role *discord.Role) er return nil } -func (s *DefaultStore) RoleRemove(guildID, roleID discord.Snowflake) error { +func (s *DefaultStore) RoleRemove(guildID discord.GuildID, roleID discord.RoleID) error { s.mut.Lock() defer s.mut.Unlock() @@ -652,7 +652,7 @@ func (s *DefaultStore) RoleRemove(guildID, roleID discord.Snowflake) error { //// -func (s *DefaultStore) VoiceState(guildID, userID discord.Snowflake) (*discord.VoiceState, error) { +func (s *DefaultStore) VoiceState(guildID discord.GuildID, userID discord.UserID) (*discord.VoiceState, error) { s.mut.Lock() defer s.mut.Unlock() @@ -670,7 +670,7 @@ func (s *DefaultStore) VoiceState(guildID, userID discord.Snowflake) (*discord.V return nil, ErrStoreNotFound } -func (s *DefaultStore) VoiceStates(guildID discord.Snowflake) ([]discord.VoiceState, error) { +func (s *DefaultStore) VoiceStates(guildID discord.GuildID) ([]discord.VoiceState, error) { s.mut.Lock() defer s.mut.Unlock() @@ -682,7 +682,7 @@ func (s *DefaultStore) VoiceStates(guildID discord.Snowflake) ([]discord.VoiceSt return append([]discord.VoiceState{}, states...), nil } -func (s *DefaultStore) VoiceStateSet(guildID discord.Snowflake, voiceState *discord.VoiceState) error { +func (s *DefaultStore) VoiceStateSet(guildID discord.GuildID, voiceState *discord.VoiceState) error { s.mut.Lock() defer s.mut.Unlock() @@ -702,7 +702,7 @@ func (s *DefaultStore) VoiceStateSet(guildID discord.Snowflake, voiceState *disc return nil } -func (s *DefaultStore) VoiceStateRemove(guildID, userID discord.Snowflake) error { +func (s *DefaultStore) VoiceStateRemove(guildID discord.GuildID, userID discord.UserID) error { s.mut.Lock() defer s.mut.Unlock() diff --git a/state/store_noop.go b/state/store_noop.go index a64deda..9bc436e 100644 --- a/state/store_noop.go +++ b/state/store_noop.go @@ -27,15 +27,15 @@ func (NoopStore) MyselfSet(*discord.User) error { return nil } -func (NoopStore) Channel(discord.Snowflake) (*discord.Channel, error) { +func (NoopStore) Channel(discord.ChannelID) (*discord.Channel, error) { return nil, ErrNotImplemented } -func (NoopStore) Channels(discord.Snowflake) ([]discord.Channel, error) { +func (NoopStore) Channels(discord.GuildID) ([]discord.Channel, error) { return nil, ErrNotImplemented } -func (NoopStore) CreatePrivateChannel(discord.Snowflake) (*discord.Channel, error) { +func (NoopStore) CreatePrivateChannel(discord.UserID) (*discord.Channel, error) { return nil, ErrNotImplemented } @@ -51,19 +51,19 @@ func (NoopStore) ChannelRemove(*discord.Channel) error { return nil } -func (NoopStore) Emoji(_, _ discord.Snowflake) (*discord.Emoji, error) { +func (NoopStore) Emoji(discord.GuildID, discord.EmojiID) (*discord.Emoji, error) { return nil, ErrNotImplemented } -func (NoopStore) Emojis(discord.Snowflake) ([]discord.Emoji, error) { +func (NoopStore) Emojis(discord.GuildID) ([]discord.Emoji, error) { return nil, ErrNotImplemented } -func (NoopStore) EmojiSet(discord.Snowflake, []discord.Emoji) error { +func (NoopStore) EmojiSet(discord.GuildID, []discord.Emoji) error { return nil } -func (NoopStore) Guild(discord.Snowflake) (*discord.Guild, error) { +func (NoopStore) Guild(discord.GuildID) (*discord.Guild, error) { return nil, ErrNotImplemented } @@ -75,31 +75,31 @@ func (NoopStore) GuildSet(*discord.Guild) error { return nil } -func (NoopStore) GuildRemove(discord.Snowflake) error { +func (NoopStore) GuildRemove(discord.GuildID) error { return nil } -func (NoopStore) Member(_, _ discord.Snowflake) (*discord.Member, error) { +func (NoopStore) Member(discord.GuildID, discord.UserID) (*discord.Member, error) { return nil, ErrNotImplemented } -func (NoopStore) Members(discord.Snowflake) ([]discord.Member, error) { +func (NoopStore) Members(discord.GuildID) ([]discord.Member, error) { return nil, ErrNotImplemented } -func (NoopStore) MemberSet(discord.Snowflake, *discord.Member) error { +func (NoopStore) MemberSet(discord.GuildID, *discord.Member) error { return nil } -func (NoopStore) MemberRemove(_, _ discord.Snowflake) error { +func (NoopStore) MemberRemove(discord.GuildID, discord.UserID) error { return nil } -func (NoopStore) Message(_, _ discord.Snowflake) (*discord.Message, error) { +func (NoopStore) Message(discord.ChannelID, discord.MessageID) (*discord.Message, error) { return nil, ErrNotImplemented } -func (NoopStore) Messages(discord.Snowflake) ([]discord.Message, error) { +func (NoopStore) Messages(discord.ChannelID) ([]discord.Message, error) { return nil, ErrNotImplemented } @@ -113,54 +113,54 @@ func (NoopStore) MessageSet(*discord.Message) error { return nil } -func (NoopStore) MessageRemove(_, _ discord.Snowflake) error { +func (NoopStore) MessageRemove(discord.ChannelID, discord.MessageID) error { return nil } -func (NoopStore) Presence(_, _ discord.Snowflake) (*discord.Presence, error) { +func (NoopStore) Presence(discord.GuildID, discord.UserID) (*discord.Presence, error) { return nil, ErrNotImplemented } -func (NoopStore) Presences(discord.Snowflake) ([]discord.Presence, error) { +func (NoopStore) Presences(discord.GuildID) ([]discord.Presence, error) { return nil, ErrNotImplemented } -func (NoopStore) PresenceSet(discord.Snowflake, *discord.Presence) error { +func (NoopStore) PresenceSet(discord.GuildID, *discord.Presence) error { return nil } -func (NoopStore) PresenceRemove(_, _ discord.Snowflake) error { +func (NoopStore) PresenceRemove(discord.GuildID, discord.UserID) error { return nil } -func (NoopStore) Role(_, _ discord.Snowflake) (*discord.Role, error) { +func (NoopStore) Role(discord.GuildID, discord.RoleID) (*discord.Role, error) { return nil, ErrNotImplemented } -func (NoopStore) Roles(discord.Snowflake) ([]discord.Role, error) { +func (NoopStore) Roles(discord.GuildID) ([]discord.Role, error) { return nil, ErrNotImplemented } -func (NoopStore) RoleSet(discord.Snowflake, *discord.Role) error { +func (NoopStore) RoleSet(discord.GuildID, *discord.Role) error { return nil } -func (NoopStore) RoleRemove(_, _ discord.Snowflake) error { +func (NoopStore) RoleRemove(discord.GuildID, discord.RoleID) error { return nil } -func (NoopStore) VoiceState(_, _ discord.Snowflake) (*discord.VoiceState, error) { +func (NoopStore) VoiceState(discord.GuildID, discord.UserID) (*discord.VoiceState, error) { return nil, ErrNotImplemented } -func (NoopStore) VoiceStates(_ discord.Snowflake) ([]discord.VoiceState, error) { +func (NoopStore) VoiceStates(discord.GuildID) ([]discord.VoiceState, error) { return nil, ErrNotImplemented } -func (NoopStore) VoiceStateSet(discord.Snowflake, *discord.VoiceState) error { +func (NoopStore) VoiceStateSet(discord.GuildID, *discord.VoiceState) error { return ErrNotImplemented } -func (NoopStore) VoiceStateRemove(_, _ discord.Snowflake) error { +func (NoopStore) VoiceStateRemove(discord.GuildID, discord.UserID) error { return ErrNotImplemented } diff --git a/utils/moreatomic/guildid_set.go b/utils/moreatomic/guildid_set.go new file mode 100644 index 0000000..5aee5ec --- /dev/null +++ b/utils/moreatomic/guildid_set.go @@ -0,0 +1,51 @@ +package moreatomic + +import ( + "sync" + + "github.com/diamondburned/arikawa/discord" +) + +type GuildIDSet struct { + set map[discord.GuildID]struct{} + mut sync.Mutex +} + +// NewGuildIDSet creates a new GuildIDSet. +func NewGuildIDSet() *GuildIDSet { + return &GuildIDSet{ + set: make(map[discord.GuildID]struct{}), + } +} + +// Add adds the passed discord.GuildID to the set. +func (s *GuildIDSet) Add(flake discord.GuildID) { + s.mut.Lock() + + s.set[flake] = struct{}{} + + s.mut.Unlock() +} + +// Contains checks whether the passed discord.GuildID is present in the set. +func (s *GuildIDSet) Contains(flake discord.GuildID) (ok bool) { + s.mut.Lock() + defer s.mut.Unlock() + + _, ok = s.set[flake] + return +} + +// Delete deletes the passed discord.GuildID from the set and returns true if +// the element is present. If not, Delete is a no-op and returns false. +func (s *GuildIDSet) Delete(flake discord.GuildID) bool { + s.mut.Lock() + defer s.mut.Unlock() + + if _, ok := s.set[flake]; ok { + delete(s.set, flake) + return true + } + + return false +} diff --git a/voice/integration_test.go b/voice/integration_test.go index beda26c..aa60a43 100644 --- a/voice/integration_test.go +++ b/voice/integration_test.go @@ -20,7 +20,7 @@ import ( type testConfig struct { BotToken string - VoiceChID discord.Snowflake + VoiceChID discord.ChannelID } func mustConfig(t *testing.T) testConfig { @@ -41,7 +41,7 @@ func mustConfig(t *testing.T) testConfig { return testConfig{ BotToken: token, - VoiceChID: id, + VoiceChID: discord.ChannelID(id), } } diff --git a/voice/session.go b/voice/session.go index 3e6b06f..aceda2e 100644 --- a/voice/session.go +++ b/voice/session.go @@ -52,7 +52,7 @@ type Session struct { speaking bool } -func NewSession(ses *session.Session, userID discord.Snowflake) *Session { +func NewSession(ses *session.Session, userID discord.UserID) *Session { return &Session{ session: ses, state: voicegateway.State{ @@ -109,17 +109,14 @@ func (s *Session) UpdateState(ev *gateway.VoiceStateUpdateEvent) { } } -func (s *Session) JoinChannel(gID, cID discord.Snowflake, muted, deafened bool) error { +func (s *Session) JoinChannel(gID discord.GuildID, cID discord.ChannelID, muted, deafened bool) error { ctx, cancel := context.WithTimeout(context.Background(), WSTimeout) defer cancel() return s.JoinChannelCtx(ctx, gID, cID, muted, deafened) } -func (s *Session) JoinChannelCtx( - ctx context.Context, - gID, cID discord.Snowflake, muted, deafened bool) error { - +func (s *Session) JoinChannelCtx(ctx context.Context, gID discord.GuildID, cID discord.ChannelID, muted, deafened bool) error { // Acquire the mutex during join, locking during IO as well. s.mut.Lock() defer s.mut.Unlock() @@ -140,7 +137,7 @@ func (s *Session) JoinChannelCtx( s.speaking = false // Ensure that if `cID` is zero that it passes null to the update event. - var channelID discord.Snowflake = -1 + var channelID discord.ChannelID = -1 if cID.Valid() { channelID = cID } @@ -278,7 +275,7 @@ func (s *Session) DisconnectCtx(ctx context.Context) error { err := s.session.Gateway.UpdateVoiceStateCtx(ctx, gateway.UpdateVoiceStateData{ GuildID: s.state.GuildID, - ChannelID: discord.NullSnowflake, + ChannelID: discord.ChannelID(discord.NullSnowflake), SelfMute: true, SelfDeaf: true, }) diff --git a/voice/voice.go b/voice/voice.go index b52b422..a804f3a 100644 --- a/voice/voice.go +++ b/voice/voice.go @@ -29,7 +29,7 @@ type Voice struct { // Session holds all of the active voice sessions. mapmutex sync.Mutex - sessions map[discord.Snowflake]*Session // guildID:Session + sessions map[discord.GuildID]*Session // Callbacks to remove the handlers. closers []func() @@ -53,7 +53,7 @@ func NewVoiceFromToken(token string) (*Voice, error) { func NewVoice(s *state.State) *Voice { v := &Voice{ State: s, - sessions: make(map[discord.Snowflake]*Session), + sessions: make(map[discord.GuildID]*Session), ErrorLog: defaultErrorHandler, } @@ -110,7 +110,7 @@ func (v *Voice) onVoiceServerUpdate(e *gateway.VoiceServerUpdateEvent) { } // GetSession gets a session for a guild with a read lock. -func (v *Voice) GetSession(guildID discord.Snowflake) (*Session, bool) { +func (v *Voice) GetSession(guildID discord.GuildID) (*Session, bool) { v.mapmutex.Lock() defer v.mapmutex.Unlock() @@ -120,7 +120,7 @@ func (v *Voice) GetSession(guildID discord.Snowflake) (*Session, bool) { } // RemoveSession removes a session. -func (v *Voice) RemoveSession(guildID discord.Snowflake) { +func (v *Voice) RemoveSession(guildID discord.GuildID) { v.mapmutex.Lock() defer v.mapmutex.Unlock() @@ -133,7 +133,7 @@ func (v *Voice) RemoveSession(guildID discord.Snowflake) { } // JoinChannel joins the specified channel in the specified guild. -func (v *Voice) JoinChannel(gID, cID discord.Snowflake, muted, deafened bool) (*Session, error) { +func (v *Voice) JoinChannel(gID discord.GuildID, cID discord.ChannelID, muted, deafened bool) (*Session, error) { // Get the stored voice session for the given guild. conn, ok := v.GetSession(gID) @@ -158,7 +158,7 @@ func (v *Voice) JoinChannel(gID, cID discord.Snowflake, muted, deafened bool) (* func (v *Voice) Close() error { err := &CloseError{ - SessionErrors: make(map[discord.Snowflake]error), + SessionErrors: make(map[discord.GuildID]error), } v.mapmutex.Lock() @@ -184,7 +184,7 @@ func (v *Voice) Close() error { } type CloseError struct { - SessionErrors map[discord.Snowflake]error + SessionErrors map[discord.GuildID]error StateErr error } diff --git a/voice/voicegateway/commands.go b/voice/voicegateway/commands.go index ea0038b..a23fd62 100644 --- a/voice/voicegateway/commands.go +++ b/voice/voicegateway/commands.go @@ -19,10 +19,10 @@ var ( // OPCode 0 // https://discordapp.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-identify-payload type IdentifyData struct { - GuildID discord.Snowflake `json:"server_id"` // yes, this should be "server_id" - UserID discord.Snowflake `json:"user_id"` - SessionID string `json:"session_id"` - Token string `json:"token"` + GuildID discord.GuildID `json:"server_id"` // yes, this should be "server_id" + UserID discord.UserID `json:"user_id"` + SessionID string `json:"session_id"` + Token string `json:"token"` } // Identify sends an Identify operation (opcode 0) to the Gateway Gateway. @@ -135,9 +135,9 @@ func (c *Gateway) SpeakingCtx(ctx context.Context, flag SpeakingFlag) error { // OPCode 7 // https://discordapp.com/developers/docs/topics/voice-connections#resuming-voice-connection-example-resume-connection-payload type ResumeData struct { - GuildID discord.Snowflake `json:"server_id"` // yes, this should be "server_id" - SessionID string `json:"session_id"` - Token string `json:"token"` + GuildID discord.GuildID `json:"server_id"` // yes, this should be "server_id" + SessionID string `json:"session_id"` + Token string `json:"token"` } // Resume sends a Resume operation (opcode 7) to the Gateway Gateway. diff --git a/voice/voicegateway/gateway.go b/voice/voicegateway/gateway.go index 2495c31..a786965 100644 --- a/voice/voicegateway/gateway.go +++ b/voice/voicegateway/gateway.go @@ -34,9 +34,9 @@ var ( // State contains state information of a voice gateway. type State struct { - GuildID discord.Snowflake - ChannelID discord.Snowflake - UserID discord.Snowflake + GuildID discord.GuildID + ChannelID discord.ChannelID + UserID discord.UserID SessionID string Token string