-
-
Notifications
You must be signed in to change notification settings - Fork 56
/
infer.go
82 lines (65 loc) · 1.78 KB
/
infer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 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
}