mirror of
https://github.com/diamondburned/arikawa.git
synced 2024-11-10 00:45:48 +00:00
83 lines
1.8 KiB
Go
83 lines
1.8 KiB
Go
// Package infer implements reflect functions that package bot uses.
|
|
//
|
|
// Functions in this package may run recursively forever. This shouldn't happen
|
|
// with Arikawa's structures, but use these functions with care.
|
|
package infer
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/diamondburned/arikawa/discord"
|
|
)
|
|
|
|
// 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")
|
|
}
|
|
|
|
// 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")
|
|
}
|
|
|
|
// UserID looks for fields with name UserID, User, or in some special cases, ID.
|
|
func UserID(event interface{}) discord.Snowflake {
|
|
return reflectID(reflect.ValueOf(event), "User")
|
|
}
|
|
|
|
func reflectID(v reflect.Value, thing string) discord.Snowflake {
|
|
if !v.IsValid() {
|
|
return 0
|
|
}
|
|
|
|
t := v.Type()
|
|
|
|
if t.Kind() == reflect.Ptr {
|
|
v = v.Elem()
|
|
|
|
// Recheck after dereferring
|
|
if !v.IsValid() {
|
|
return 0
|
|
}
|
|
|
|
t = v.Type()
|
|
}
|
|
|
|
if t.Kind() != reflect.Struct {
|
|
return 0
|
|
}
|
|
|
|
numFields := t.NumField()
|
|
|
|
for i := 0; i < numFields; i++ {
|
|
field := t.Field(i)
|
|
fType := field.Type
|
|
|
|
if fType.Kind() == reflect.Ptr {
|
|
fType = fType.Elem()
|
|
}
|
|
|
|
switch fType.Kind() {
|
|
case reflect.Struct:
|
|
if chID := reflectID(v.Field(i), thing); chID.Valid() {
|
|
return chID
|
|
}
|
|
case reflect.Int64:
|
|
if field.Name == thing+"ID" {
|
|
// grab value real quick
|
|
return discord.Snowflake(v.Field(i).Int())
|
|
}
|
|
|
|
// Special case where the struct name has Channel in it
|
|
if field.Name == "ID" && strings.Contains(t.Name(), thing) {
|
|
return discord.Snowflake(v.Field(i).Int())
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|