-
Notifications
You must be signed in to change notification settings - Fork 4
/
subcommand.go
176 lines (152 loc) · 4.4 KB
/
subcommand.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package gommand
import (
"sort"
"strings"
)
// CommandGroup is used to have a group of commands which will be executed as sub-commands.
type CommandGroup struct {
// Name is used to define the category name.
Name string `json:"name"`
// Aliases is used to define aliases for this command group.
Aliases []string `json:"aliases"`
// Description is used to define a group description.
Description string `json:"description"`
// Category is used to define a group category.
Category CategoryInterface `json:"category"`
// Cooldown is used to define a group cooldown.
Cooldown Cooldown `json:"cooldown"`
// PermissionValidators defines the permission validators for this group.
PermissionValidators []PermissionValidator `json:"-"`
// Middleware is used to define the sub-command middleware. Note that this applies to all items in the group.
Middleware []Middleware `json:"-"`
// NoCommandSpecified is the command to call when no command is specified.
NoCommandSpecified CommandInterface
// Defines the sub-commands.
subcommands map[string]CommandInterface
}
// GetName is used to get the name.
func (g *CommandGroup) GetName() string {
return g.Name
}
// GetAliases is used to get the aliases.
func (g *CommandGroup) GetAliases() []string {
if g.Aliases == nil {
return []string{}
}
return g.Aliases
}
// GetDescription is used to get the description.
func (g *CommandGroup) GetDescription() string {
return g.Description
}
// GetUsage is used to get the usage.
func (g *CommandGroup) GetUsage() string {
x := "<"
keys := make([]string, len(g.subcommands))
i := 0
for k := range g.subcommands {
keys[i] = k
i++
}
sort.Strings(keys)
for _, cmdname := range keys {
x += cmdname + "/"
}
x = x[:len(x)-1]
if len(x) == 0 {
if g.NoCommandSpecified != nil {
return g.NoCommandSpecified.GetUsage()
}
return ""
}
return x + ">"
}
// GetCategory is used to get the category.
func (g *CommandGroup) GetCategory() CategoryInterface {
return g.Category
}
// GetPermissionValidators is used to get the permission validators.
func (g *CommandGroup) GetPermissionValidators() []PermissionValidator {
return g.PermissionValidators
}
// GetArgTransformers is used to get the arg transformers.
func (g *CommandGroup) GetArgTransformers() []ArgTransformer {
return []ArgTransformer{
{
Function: StringTransformer,
Optional: true,
},
{
Remainder: true,
Optional: true,
Function: StringTransformer,
},
}
}
// GetCooldown is used to get the cooldown.
func (g *CommandGroup) GetCooldown() Cooldown {
return g.Cooldown
}
// GetMiddleware is used to get the middleware.
func (g *CommandGroup) GetMiddleware() []Middleware {
return g.Middleware
}
// CommandFunction is the command function which will be called.
func (g *CommandGroup) CommandFunction(ctx *Context) error {
cmdname, ok := ctx.Args[0].(string)
if !ok {
// Handle the no command specified event if it is set.
if g.NoCommandSpecified != nil {
return runCommand(ctx, strings.NewReader(""), g.NoCommandSpecified)
}
// Send an error to the router.
return &CommandBlank{err: "This group expects a command but none was given."}
}
args, _ := ctx.Args[1].(string)
subcommand, ok := g.subcommands[strings.ToLower(cmdname)]
if ok {
// Return this command handler.
return runCommand(ctx, strings.NewReader(args), subcommand)
}
return &CommandNotFound{err: "The command specified for the group was not found."}
}
// Init is used to initialise the commands group.
func (g *CommandGroup) Init() {
if g.NoCommandSpecified != nil {
g.NoCommandSpecified.Init()
}
for _, v := range g.GetSubcommands() {
v.Init()
}
}
// AddCommand is used to add a command to the group.
func (g *CommandGroup) AddCommand(cmd CommandInterface) {
if g.subcommands == nil {
g.subcommands = map[string]CommandInterface{}
}
cmdname := strings.ToLower(cmd.GetName())
g.subcommands[cmdname] = cmd
for _, alias := range cmd.GetAliases() {
g.subcommands[strings.ToLower(alias)] = cmd
}
}
// GetSubcommands is used to get all the sub-commands of this group.
func (g *CommandGroup) GetSubcommands() []CommandInterface {
if g.subcommands == nil {
g.subcommands = map[string]CommandInterface{}
}
uniques := make([]CommandInterface, 0, len(g.subcommands))
for _, v := range g.subcommands {
isUnique := true
for _, x := range uniques {
if v == x {
isUnique = false
break
}
}
if isUnique {
uniques = append(uniques, v)
}
}
return uniques
}