mirror of
https://github.com/diamondburned/arikawa.git
synced 2024-09-28 13:19:06 +00:00
Merge pull request #40 from mavolin/29-option-types
This commit is contained in:
commit
d4bdf700f3
|
@ -3,7 +3,7 @@ package api
|
||||||
import (
|
import (
|
||||||
"github.com/diamondburned/arikawa/discord"
|
"github.com/diamondburned/arikawa/discord"
|
||||||
"github.com/diamondburned/arikawa/utils/httputil"
|
"github.com/diamondburned/arikawa/utils/httputil"
|
||||||
"github.com/diamondburned/arikawa/utils/json"
|
"github.com/diamondburned/arikawa/utils/json/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
var EndpointChannels = Endpoint + "channels/"
|
var EndpointChannels = Endpoint + "channels/"
|
||||||
|
@ -27,8 +27,8 @@ type CreateChannelData struct {
|
||||||
|
|
||||||
UserRateLimit discord.Seconds `json:"rate_limit_per_user,omitempty"`
|
UserRateLimit discord.Seconds `json:"rate_limit_per_user,omitempty"`
|
||||||
|
|
||||||
NSFW bool `json:"nsfw"`
|
NSFW bool `json:"nsfw,omitempty"`
|
||||||
Position int `json:"position,omitempty"`
|
Position option.Int `json:"position,omitempty"`
|
||||||
|
|
||||||
Permissions []discord.Overwrite `json:"permission_overwrites,omitempty"`
|
Permissions []discord.Overwrite `json:"permission_overwrites,omitempty"`
|
||||||
CategoryID discord.Snowflake `json:"parent_id,string,omitempty"`
|
CategoryID discord.Snowflake `json:"parent_id,string,omitempty"`
|
||||||
|
@ -48,7 +48,7 @@ func (c *Client) CreateChannel(
|
||||||
|
|
||||||
type MoveChannelData struct {
|
type MoveChannelData struct {
|
||||||
ID discord.Snowflake `json:"id"`
|
ID discord.Snowflake `json:"id"`
|
||||||
Position json.OptionInt `json:"position"`
|
Position option.Int `json:"position"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MoveChannel modifies the position of channels in the guild. Requires
|
// MoveChannel modifies the position of channels in the guild. Requires
|
||||||
|
@ -68,22 +68,24 @@ func (c *Client) Channel(channelID discord.Snowflake) (*discord.Channel, error)
|
||||||
|
|
||||||
type ModifyChannelData struct {
|
type ModifyChannelData struct {
|
||||||
// All types
|
// All types
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Position json.OptionInt `json:"position,omitempty"`
|
// Type allows conversions between text and news channels.
|
||||||
Permissions []discord.Overwrite `json:"permission_overwrites,omitempty"`
|
Type *discord.ChannelType `json:"type,omitempty"`
|
||||||
|
Position option.Int `json:"position,omitempty"`
|
||||||
|
Permissions *[]discord.Overwrite `json:"permission_overwrites,omitempty"`
|
||||||
|
|
||||||
// Text only
|
// Text only
|
||||||
Topic json.OptionString `json:"topic,omitempty"`
|
Topic option.String `json:"topic,omitempty"`
|
||||||
NSFW json.OptionBool `json:"nsfw,omitempty"`
|
NSFW option.Bool `json:"nsfw,omitempty"`
|
||||||
|
|
||||||
// 0-21600 seconds, refer to (discord.Channel).UserRateLimit.
|
// 0-21600 seconds, refer to (discord.Channel).UserRateLimit.
|
||||||
UserRateLimit json.OptionInt `json:"rate_limit_per_user,omitempty"`
|
UserRateLimit option.Int `json:"rate_limit_per_user,omitempty"`
|
||||||
|
|
||||||
// Voice only
|
// Voice only
|
||||||
// 8000 - 96000 (or 128000 for Nitro)
|
// 8000 - 96000 (or 128000 for Nitro)
|
||||||
VoiceBitrate json.OptionUint `json:"bitrate,omitempty"`
|
VoiceBitrate option.Uint `json:"bitrate,omitempty"`
|
||||||
// 0 no limit, 1-99
|
// 0 no limit, 1-99
|
||||||
VoiceUserLimit json.OptionUint `json:"user_limit,omitempty"`
|
VoiceUserLimit option.Uint `json:"user_limit,omitempty"`
|
||||||
|
|
||||||
// Text OR Voice
|
// Text OR Voice
|
||||||
CategoryID discord.Snowflake `json:"parent_id,string,omitempty"`
|
CategoryID discord.Snowflake `json:"parent_id,string,omitempty"`
|
||||||
|
|
26
api/guild.go
26
api/guild.go
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/diamondburned/arikawa/discord" // for clarity
|
"github.com/diamondburned/arikawa/discord" // for clarity
|
||||||
"github.com/diamondburned/arikawa/utils/httputil"
|
"github.com/diamondburned/arikawa/utils/httputil"
|
||||||
"github.com/diamondburned/arikawa/utils/json"
|
"github.com/diamondburned/arikawa/utils/json/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
var EndpointGuilds = Endpoint + "guilds/"
|
var EndpointGuilds = Endpoint + "guilds/"
|
||||||
|
@ -17,9 +17,9 @@ type CreateGuildData struct {
|
||||||
Icon Image `json:"image,omitempty"`
|
Icon Image `json:"image,omitempty"`
|
||||||
|
|
||||||
// package dc is just package discord
|
// package dc is just package discord
|
||||||
Verification discord.Verification `json:"verification_level"`
|
Verification *discord.Verification `json:"verification_level"`
|
||||||
Notification discord.Notification `json:"default_message_notifications"`
|
Notification *discord.Notification `json:"default_message_notifications"`
|
||||||
ExplicitFilter discord.ExplicitFilter `json:"explicit_content_filter"`
|
ExplicitFilter *discord.ExplicitFilter `json:"explicit_content_filter"`
|
||||||
|
|
||||||
// [0] (First entry) is ALWAYS @everyone.
|
// [0] (First entry) is ALWAYS @everyone.
|
||||||
Roles []discord.Role `json:"roles,omitempty"`
|
Roles []discord.Role `json:"roles,omitempty"`
|
||||||
|
@ -134,16 +134,16 @@ func (c *Client) LeaveGuild(id discord.Snowflake) error {
|
||||||
|
|
||||||
// https://discordapp.com/developers/docs/resources/guild#modify-guild-json-params
|
// https://discordapp.com/developers/docs/resources/guild#modify-guild-json-params
|
||||||
type ModifyGuildData struct {
|
type ModifyGuildData struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Region json.OptionString `json:"region,omitempty"`
|
Region option.String `json:"region,omitempty"`
|
||||||
|
|
||||||
// package d is just package discord
|
// package d is just package discord
|
||||||
Verification *discord.Verification `json:"verification_level,omitempty"`
|
Verification *discord.Verification `json:"verification_level,omitempty"` // nullable
|
||||||
Notification *discord.Notification `json:"default_message_notifications,omitempty"`
|
Notification *discord.Notification `json:"default_message_notifications,omitempty"` // nullable
|
||||||
ExplicitFilter *discord.ExplicitFilter `json:"explicit_content_filter,omitempty"`
|
ExplicitFilter *discord.ExplicitFilter `json:"explicit_content_filter,omitempty"` // nullable
|
||||||
|
|
||||||
AFKChannelID discord.Snowflake `json:"afk_channel_id,string,omitempty"`
|
AFKChannelID discord.Snowflake `json:"afk_channel_id,string,omitempty"`
|
||||||
AFKTimeout discord.Seconds `json:"afk_timeout,omitempty"`
|
AFKTimeout option.Seconds `json:"afk_timeout,omitempty"`
|
||||||
|
|
||||||
OwnerID discord.Snowflake `json:"owner_id,omitempty"`
|
OwnerID discord.Snowflake `json:"owner_id,omitempty"`
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ type ModifyGuildData struct {
|
||||||
RulesChannelID discord.Snowflake `json:"rules_channel_id,omitempty"`
|
RulesChannelID discord.Snowflake `json:"rules_channel_id,omitempty"`
|
||||||
PublicUpdatesChannelID discord.Snowflake `json:"public_updates_channel_id,omitempty"`
|
PublicUpdatesChannelID discord.Snowflake `json:"public_updates_channel_id,omitempty"`
|
||||||
|
|
||||||
PreferredLocale json.OptionString `json:"preferred_locale,omitempty"`
|
PreferredLocale option.String `json:"preferred_locale,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ModifyGuild(id discord.Snowflake, data ModifyGuildData) (*discord.Guild, error) {
|
func (c *Client) ModifyGuild(id discord.Snowflake, data ModifyGuildData) (*discord.Guild, error) {
|
||||||
|
@ -236,8 +236,8 @@ func (c *Client) AttachIntegration(
|
||||||
// https://discord.com/developers/docs/resources/guild#modify-guild-integration-json-params
|
// https://discord.com/developers/docs/resources/guild#modify-guild-integration-json-params
|
||||||
type ModifyIntegrationData struct {
|
type ModifyIntegrationData struct {
|
||||||
ExpireBehavior *discord.ExpireBehavior `json:"expire_behavior"`
|
ExpireBehavior *discord.ExpireBehavior `json:"expire_behavior"`
|
||||||
ExpireGracePeriod json.OptionInt `json:"expire_grace_period"`
|
ExpireGracePeriod option.Int `json:"expire_grace_period"`
|
||||||
EnableEmoticons json.OptionBool `json:"enable_emoticons"` // limited to twitch
|
EnableEmoticons option.Bool `json:"enable_emoticons"` // limited to twitch
|
||||||
}
|
}
|
||||||
|
|
||||||
// ModifyIntegration requires MANAGE_GUILD.
|
// ModifyIntegration requires MANAGE_GUILD.
|
||||||
|
|
|
@ -3,7 +3,7 @@ package api
|
||||||
import (
|
import (
|
||||||
"github.com/diamondburned/arikawa/discord"
|
"github.com/diamondburned/arikawa/discord"
|
||||||
"github.com/diamondburned/arikawa/utils/httputil"
|
"github.com/diamondburned/arikawa/utils/httputil"
|
||||||
"github.com/diamondburned/arikawa/utils/json"
|
"github.com/diamondburned/arikawa/utils/json/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Client) Member(guildID, userID discord.Snowflake) (*discord.Member, error) {
|
func (c *Client) Member(guildID, userID discord.Snowflake) (*discord.Member, error) {
|
||||||
|
@ -80,9 +80,9 @@ func (c *Client) MembersAfter(
|
||||||
|
|
||||||
// AnyMemberData, all fields are optional.
|
// AnyMemberData, all fields are optional.
|
||||||
type AnyMemberData struct {
|
type AnyMemberData struct {
|
||||||
Nick json.OptionString `json:"nick,omitempty"`
|
Nick option.String `json:"nick,omitempty"`
|
||||||
Mute json.OptionBool `json:"mute,omitempty"`
|
Mute option.Bool `json:"mute,omitempty"`
|
||||||
Deaf json.OptionBool `json:"deaf,omitempty"`
|
Deaf option.Bool `json:"deaf,omitempty"`
|
||||||
|
|
||||||
Roles *[]discord.Snowflake `json:"roles,omitempty"`
|
Roles *[]discord.Snowflake `json:"roles,omitempty"`
|
||||||
|
|
||||||
|
|
16
api/role.go
16
api/role.go
|
@ -3,6 +3,7 @@ package api
|
||||||
import (
|
import (
|
||||||
"github.com/diamondburned/arikawa/discord"
|
"github.com/diamondburned/arikawa/discord"
|
||||||
"github.com/diamondburned/arikawa/utils/httputil"
|
"github.com/diamondburned/arikawa/utils/httputil"
|
||||||
|
"github.com/diamondburned/arikawa/utils/json/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Client) AddRole(guildID, userID, roleID discord.Snowflake) error {
|
func (c *Client) AddRole(guildID, userID, roleID discord.Snowflake) error {
|
||||||
|
@ -23,7 +24,7 @@ func (c *Client) Roles(guildID discord.Snowflake) ([]discord.Role, error) {
|
||||||
EndpointGuilds+guildID.String()+"/roles")
|
EndpointGuilds+guildID.String()+"/roles")
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnyRoleData struct {
|
type CreateRoleData struct {
|
||||||
Name string `json:"name,omitempty"` // "new role"
|
Name string `json:"name,omitempty"` // "new role"
|
||||||
Color discord.Color `json:"color,omitempty"` // 0
|
Color discord.Color `json:"color,omitempty"` // 0
|
||||||
Hoist bool `json:"hoist,omitempty"` // false (show role separately)
|
Hoist bool `json:"hoist,omitempty"` // false (show role separately)
|
||||||
|
@ -32,7 +33,7 @@ type AnyRoleData struct {
|
||||||
Permissions discord.Permissions `json:"permissions,omitempty"` // @everyone
|
Permissions discord.Permissions `json:"permissions,omitempty"` // @everyone
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) CreateRole(guildID discord.Snowflake, data AnyRoleData) (*discord.Role, error) {
|
func (c *Client) CreateRole(guildID discord.Snowflake, data CreateRoleData) (*discord.Role, error) {
|
||||||
var role *discord.Role
|
var role *discord.Role
|
||||||
return role, c.RequestJSON(
|
return role, c.RequestJSON(
|
||||||
&role, "POST",
|
&role, "POST",
|
||||||
|
@ -60,9 +61,18 @@ func (c *Client) MoveRole(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ModifyRoleData struct {
|
||||||
|
Name string `json:"name,omitempty"` // "new role"
|
||||||
|
Color option.Color `json:"color,omitempty"` // 0
|
||||||
|
Hoist option.Bool `json:"hoist,omitempty"` // false (show role separately)
|
||||||
|
|
||||||
|
Mentionable option.Bool `json:"mentionable,omitempty"` // false
|
||||||
|
Permissions discord.Permissions `json:"permissions,omitempty"` // @everyone
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) ModifyRole(
|
func (c *Client) ModifyRole(
|
||||||
guildID, roleID discord.Snowflake,
|
guildID, roleID discord.Snowflake,
|
||||||
data AnyRoleData) (*discord.Role, error) {
|
data ModifyRoleData) (*discord.Role, error) {
|
||||||
|
|
||||||
var role *discord.Role
|
var role *discord.Role
|
||||||
return role, c.RequestJSON(
|
return role, c.RequestJSON(
|
||||||
|
|
|
@ -23,7 +23,7 @@ func (c *Client) Me() (*discord.User, error) {
|
||||||
|
|
||||||
type ModifySelfData struct {
|
type ModifySelfData struct {
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
Avatar Image `json:"image,omitempty"`
|
Avatar *Image `json:"image,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ModifyMe(data ModifySelfData) (*discord.User, error) {
|
func (c *Client) ModifyMe(data ModifySelfData) (*discord.User, error) {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/diamondburned/arikawa/utils/json"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/diamondburned/arikawa/utils/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuditLog struct {
|
type AuditLog struct {
|
||||||
|
|
|
@ -58,14 +58,14 @@ func (ch Channel) IconURL() string {
|
||||||
|
|
||||||
type ChannelType uint8
|
type ChannelType uint8
|
||||||
|
|
||||||
const (
|
var (
|
||||||
GuildText ChannelType = iota
|
GuildText ChannelType = 0
|
||||||
DirectMessage
|
DirectMessage ChannelType = 1
|
||||||
GuildVoice
|
GuildVoice ChannelType = 2
|
||||||
GroupDM
|
GroupDM ChannelType = 3
|
||||||
GuildCategory
|
GuildCategory ChannelType = 4
|
||||||
GuildNews
|
GuildNews ChannelType = 5
|
||||||
GuildStore
|
GuildStore ChannelType = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
type Overwrite struct {
|
type Overwrite struct {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/diamondburned/arikawa/utils/json/nullable"
|
||||||
|
)
|
||||||
|
|
||||||
// Guild.MaxPresences is 5000 when it's 0.
|
// Guild.MaxPresences is 5000 when it's 0.
|
||||||
const DefaultMaxPresences = 5000
|
const DefaultMaxPresences = 5000
|
||||||
|
|
||||||
|
@ -49,38 +53,85 @@ const (
|
||||||
Banner GuildFeature = "BANNER"
|
Banner GuildFeature = "BANNER"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExplicitFilter uint8
|
// ExplicitFilter is the explicit content filter level of a guild.
|
||||||
|
type ExplicitFilter nullable.Enum
|
||||||
|
|
||||||
const (
|
var (
|
||||||
NoContentFilter ExplicitFilter = iota
|
// NullExplicitFilter serialized to JSON null.
|
||||||
MembersWithoutRoles
|
// This should only be used on nullable fields.
|
||||||
AllMembers
|
NullExplicitFilter ExplicitFilter = nullable.EnumNull
|
||||||
|
// NoContentFilter disables content filtering for the guild.
|
||||||
|
NoContentFilter ExplicitFilter = 0
|
||||||
|
// MembersWithoutRoles filters only members without roles.
|
||||||
|
MembersWithoutRoles ExplicitFilter = 1
|
||||||
|
// AllMembers enables content filtering for all members.
|
||||||
|
AllMembers ExplicitFilter = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
type Notification uint8
|
func (f *ExplicitFilter) UnmarshalJSON(b []byte) error {
|
||||||
|
i, err := nullable.EnumFromJSON(b)
|
||||||
|
*f = ExplicitFilter(i)
|
||||||
|
|
||||||
const (
|
return err
|
||||||
AllMessages Notification = iota
|
}
|
||||||
OnlyMentions
|
|
||||||
|
func (f ExplicitFilter) MarshalJSON() ([]byte, error) {
|
||||||
|
return nullable.EnumToJSON(nullable.Enum(f)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notification is the default message notification level of a guild.
|
||||||
|
type Notification nullable.Enum
|
||||||
|
|
||||||
|
var (
|
||||||
|
// NullNotification serialized to JSON null.
|
||||||
|
// This should only be used on nullable fields.
|
||||||
|
NullNotification Notification = nullable.EnumNull
|
||||||
|
// AllMessages sends notifications for all messages.
|
||||||
|
AllMessages Notification = 0
|
||||||
|
// OnlyMentions sends notifications only on mention.
|
||||||
|
OnlyMentions Notification = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
type Verification uint8
|
func (n *Notification) UnmarshalJSON(b []byte) error {
|
||||||
|
i, err := nullable.EnumFromJSON(b)
|
||||||
|
*n = Notification(i)
|
||||||
|
|
||||||
const (
|
return err
|
||||||
NoVerification Verification = iota
|
}
|
||||||
|
|
||||||
|
func (n Notification) MarshalJSON() ([]byte, error) { return nullable.EnumToJSON(nullable.Enum(n)), nil }
|
||||||
|
|
||||||
|
// Verification is the verification level required for a guild.
|
||||||
|
type Verification nullable.Enum
|
||||||
|
|
||||||
|
var (
|
||||||
|
// NullVerification serialized to JSON null.
|
||||||
|
// This should only be used on nullable fields.
|
||||||
|
NullVerification Verification = nullable.EnumNull
|
||||||
|
// NoVerification required no verification.
|
||||||
|
NoVerification Verification = 0
|
||||||
// LowVerification requires a verified email
|
// LowVerification requires a verified email
|
||||||
LowVerification
|
LowVerification Verification = 1
|
||||||
// MediumVerification requires the user be registered for at least 5
|
// MediumVerification requires the user be registered for at least 5
|
||||||
// minutes.
|
// minutes.
|
||||||
MediumVerification
|
MediumVerification Verification = 2
|
||||||
// HighVerification requires the member be in the server for more than 10
|
// HighVerification requires the member be in the server for more than 10
|
||||||
// minutes.
|
// minutes.
|
||||||
HighVerification
|
HighVerification Verification = 3
|
||||||
// VeryHighVerification requires the member to have a verified phone
|
// VeryHighVerification requires the member to have a verified phone
|
||||||
// number.
|
// number.
|
||||||
VeryHighVerification
|
VeryHighVerification Verification = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (v *Verification) UnmarshalJSON(b []byte) error {
|
||||||
|
i, err := nullable.EnumFromJSON(b)
|
||||||
|
*v = Verification(i)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Verification) MarshalJSON() ([]byte, error) { return nullable.EnumToJSON(nullable.Enum(v)), nil }
|
||||||
|
|
||||||
// Service is used for guild integrations and user connections.
|
// Service is used for guild integrations and user connections.
|
||||||
type Service string
|
type Service string
|
||||||
|
|
||||||
|
|
14
utils/json/nullable/bool.go
Normal file
14
utils/json/nullable/bool.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package nullable
|
||||||
|
|
||||||
|
// Bool is a nullable version of a bool.
|
||||||
|
type Bool *bool
|
||||||
|
|
||||||
|
var (
|
||||||
|
True = newBool(true)
|
||||||
|
False = newBool(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
// newBool creates a new Bool with the value of the passed bool.
|
||||||
|
func newBool(b bool) Bool {
|
||||||
|
return &b
|
||||||
|
}
|
34
utils/json/nullable/enum.go
Normal file
34
utils/json/nullable/enum.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package nullable
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
// EnumNull is the value used to represent JSON null.
|
||||||
|
// It should never be used as a value, as it won't get serialized as such.
|
||||||
|
const EnumNull = -1
|
||||||
|
|
||||||
|
// Enum is a nullable version of a uint8.
|
||||||
|
// Enum values should only consist of positive values, as negative values are reserved for internal constants, such as
|
||||||
|
// EnumNull.
|
||||||
|
// This also mean that only 7 of the 8 Bit will be available for storage.
|
||||||
|
type Enum int8
|
||||||
|
|
||||||
|
// Int8ToJSON converts the passed Enum to a byte slice with it's JSON representation.
|
||||||
|
func EnumToJSON(i Enum) []byte {
|
||||||
|
if i == EnumNull {
|
||||||
|
return []byte("null")
|
||||||
|
} else {
|
||||||
|
return []byte(strconv.Itoa(int(i)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8FromJSON decodes the Enum stored as JSON src the passed byte slice.
|
||||||
|
func EnumFromJSON(b []byte) (Enum, error) {
|
||||||
|
s := string(b)
|
||||||
|
|
||||||
|
if s == "null" {
|
||||||
|
return EnumNull, nil
|
||||||
|
} else {
|
||||||
|
i, err := strconv.ParseUint(s, 10, 7)
|
||||||
|
return Enum(i), err
|
||||||
|
}
|
||||||
|
}
|
83
utils/json/nullable/enum_test.go
Normal file
83
utils/json/nullable/enum_test.go
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package nullable
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInt8ToJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
src Enum
|
||||||
|
expect []byte
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "null",
|
||||||
|
src: EnumNull,
|
||||||
|
expect: []byte("null"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "value",
|
||||||
|
src: 12,
|
||||||
|
expect: []byte("12"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range testCases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
actual := EnumToJSON(c.src)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(actual, c.expect) {
|
||||||
|
t.Errorf("expected nullable.Int8ToJSON to return: %+v, but got: %+v", c.expect, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInt8FromJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
src []byte
|
||||||
|
expect Enum
|
||||||
|
err bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "null",
|
||||||
|
src: []byte("null"),
|
||||||
|
expect: EnumNull,
|
||||||
|
err: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "value",
|
||||||
|
src: []byte("12"),
|
||||||
|
expect: 12,
|
||||||
|
err: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid input",
|
||||||
|
src: []byte("NaN"),
|
||||||
|
expect: 0,
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range testCases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
actual, err := EnumFromJSON(c.src)
|
||||||
|
|
||||||
|
if c.err {
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected nullable.Int8FromJSON to return an error, but it did not")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !reflect.DeepEqual(actual, c.expect) {
|
||||||
|
t.Errorf("expected nullable.Int8FromJSON to return: %+v, but got: %+v", c.expect, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("nullable.Int8FromJSON returned an error: %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
2
utils/json/nullable/nullable.go
Normal file
2
utils/json/nullable/nullable.go
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
// Package nullable provides nullable types that get serialized to JSON null.
|
||||||
|
package nullable
|
25
utils/json/nullable/number.go
Normal file
25
utils/json/nullable/number.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package nullable
|
||||||
|
|
||||||
|
type (
|
||||||
|
// Uint is a nullable version of an unsigned integer (uint).
|
||||||
|
Uint *uint
|
||||||
|
// Int is a nullable version of an integer (int).
|
||||||
|
Int *int
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ZeroUint is a Uint with 0 as value.
|
||||||
|
ZeroUint = NewUint(0)
|
||||||
|
// ZeroInt is an Int with 0 as value.
|
||||||
|
ZeroInt = NewInt(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewUint creates a new Uint using the value of the passed uint.
|
||||||
|
func NewUint(u uint) Uint {
|
||||||
|
return &u
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInt creates a new Int using the value of the passed int.
|
||||||
|
func NewInt(i int) Int {
|
||||||
|
return &i
|
||||||
|
}
|
12
utils/json/nullable/string.go
Normal file
12
utils/json/nullable/string.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package nullable
|
||||||
|
|
||||||
|
// String is a nullable version of a string.
|
||||||
|
type String *string
|
||||||
|
|
||||||
|
// EmptyString is a zero-length string.
|
||||||
|
var EmptyString = NewString("")
|
||||||
|
|
||||||
|
// NewString creates a new String with the value of the passed string.
|
||||||
|
func NewString(s string) String {
|
||||||
|
return &s
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
package json
|
|
||||||
|
|
||||||
type (
|
|
||||||
OptionBool = *bool
|
|
||||||
OptionString = *string
|
|
||||||
OptionUint = *uint
|
|
||||||
OptionInt = *int
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
True = getBool(true)
|
|
||||||
False = getBool(false)
|
|
||||||
|
|
||||||
ZeroUint = Uint(0)
|
|
||||||
ZeroInt = Int(0)
|
|
||||||
|
|
||||||
EmptyString = String("")
|
|
||||||
)
|
|
||||||
|
|
||||||
func Uint(u uint) OptionUint {
|
|
||||||
return &u
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int(i int) OptionInt {
|
|
||||||
return &i
|
|
||||||
}
|
|
||||||
|
|
||||||
func String(s string) OptionString {
|
|
||||||
return &s
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBool(Bool bool) OptionBool {
|
|
||||||
return &Bool
|
|
||||||
}
|
|
12
utils/json/option/bool.go
Normal file
12
utils/json/option/bool.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
// Bool is the option type for bool.
|
||||||
|
type Bool *bool
|
||||||
|
|
||||||
|
var (
|
||||||
|
True = newBool(true)
|
||||||
|
False = newBool(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
// newBool creates a new Bool with the value of the passed bool.
|
||||||
|
func newBool(b bool) Bool { return &b }
|
22
utils/json/option/custom.go
Normal file
22
utils/json/option/custom.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
import "github.com/diamondburned/arikawa/discord"
|
||||||
|
|
||||||
|
// ================================ Seconds ================================
|
||||||
|
|
||||||
|
// Seconds is the option type for discord.Seconds.
|
||||||
|
type Seconds *discord.Seconds
|
||||||
|
|
||||||
|
// ZeroSeconds are 0 Seconds.
|
||||||
|
var ZeroSeconds = NewSeconds(0)
|
||||||
|
|
||||||
|
// NewString creates a new Seconds with the value of the passed discord.Seconds.
|
||||||
|
func NewSeconds(s discord.Seconds) Seconds { return &s }
|
||||||
|
|
||||||
|
// ================================ Color ================================
|
||||||
|
|
||||||
|
// Color is the option type for discord.Color.
|
||||||
|
type Color *discord.Color
|
||||||
|
|
||||||
|
// NewString creates a new Color with the value of the passed discord.Color.
|
||||||
|
func NewColor(s discord.Color) Color { return &s }
|
23
utils/json/option/number.go
Normal file
23
utils/json/option/number.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
// ================================ Uint ================================
|
||||||
|
|
||||||
|
// Uint is the option type for unsigned integers (uint).
|
||||||
|
type Uint *uint
|
||||||
|
|
||||||
|
// ZeroUint is a Uint with 0 as value.
|
||||||
|
var ZeroUint = NewUint(0)
|
||||||
|
|
||||||
|
// NewUint creates a new Uint using the value of the passed uint.
|
||||||
|
func NewUint(u uint) Uint { return &u }
|
||||||
|
|
||||||
|
// ================================ Int ================================
|
||||||
|
|
||||||
|
// Int is the option type for integers (int).
|
||||||
|
type Int *int
|
||||||
|
|
||||||
|
// ZeroInt is an Int with 0 as value.
|
||||||
|
var ZeroInt = NewInt(0)
|
||||||
|
|
||||||
|
// NewInt creates a new Int using the value of the passed int.
|
||||||
|
func NewInt(i int) Int { return &i }
|
5
utils/json/option/option.go
Normal file
5
utils/json/option/option.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// Package option provides the ability to create omittable primitives.
|
||||||
|
// This is accomplished by pointerrizing common primitive types so that they may assume a nil value, which is considered
|
||||||
|
// as omitted by encoding/json.
|
||||||
|
// To generate pointerrized primitives, there are helper functions `NewT` for each option type.
|
||||||
|
package option
|
10
utils/json/option/string.go
Normal file
10
utils/json/option/string.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
// String is the option type for strings.
|
||||||
|
type String *string
|
||||||
|
|
||||||
|
// EmptyString is a zero-length string.
|
||||||
|
var EmptyString = NewString("")
|
||||||
|
|
||||||
|
// NewString creates a new String with the value of the passed string.
|
||||||
|
func NewString(s string) String { return &s }
|
Loading…
Reference in a new issue