89 lines
1.5 KiB
Go
89 lines
1.5 KiB
Go
|
package commands
|
||
|
|
||
|
import "strings"
|
||
|
|
||
|
const (
|
||
|
ArgumentTypeBasic = iota
|
||
|
ArgumentTypeUserMention
|
||
|
ArgumentTypeChannelMention
|
||
|
)
|
||
|
|
||
|
func parseCommandUsage(prefix string) *CommandHolder {
|
||
|
holder := &CommandHolder{}
|
||
|
|
||
|
holder.Name = prefix
|
||
|
holder.Usage = prefix
|
||
|
|
||
|
if idx := strings.Index(prefix, " "); idx != -1 {
|
||
|
holder.Name = prefix[0:idx]
|
||
|
|
||
|
prefix = prefix[idx+1:]
|
||
|
|
||
|
// Parse out command arguments, example:
|
||
|
// test <arg1> [optional arg2]
|
||
|
// Walk through string, match < and >, [ and ]
|
||
|
holder.Arguments = make(map[string]*CommandArgument)
|
||
|
|
||
|
str := prefix
|
||
|
|
||
|
var name string
|
||
|
|
||
|
var index int
|
||
|
|
||
|
for {
|
||
|
if len(str) == 0 {
|
||
|
break
|
||
|
}
|
||
|
|
||
|
ch := str[0]
|
||
|
|
||
|
if ch == '<' || ch == '[' {
|
||
|
// Scan until closing arrow or end of string
|
||
|
for i := 1; i < len(str); i++ {
|
||
|
if (str[i] == '>' || str[i] == ']') && str[i-1] != '\\' {
|
||
|
name = str[1:i]
|
||
|
if i+2 < len(str) {
|
||
|
str = str[i+2:]
|
||
|
} else {
|
||
|
str = ""
|
||
|
}
|
||
|
|
||
|
required := false
|
||
|
|
||
|
if ch == '<' {
|
||
|
required = true
|
||
|
|
||
|
holder.RequiredArgumentCount++
|
||
|
}
|
||
|
|
||
|
t := ArgumentTypeBasic
|
||
|
|
||
|
if name[0] == '@' {
|
||
|
t = ArgumentTypeUserMention
|
||
|
name = name[1:]
|
||
|
} else if name[0] == '#' {
|
||
|
t = ArgumentTypeChannelMention
|
||
|
name = name[1:]
|
||
|
}
|
||
|
|
||
|
holder.Arguments[name] = &CommandArgument{
|
||
|
Index: index,
|
||
|
Name: name,
|
||
|
Required: required,
|
||
|
Type: t,
|
||
|
}
|
||
|
|
||
|
index++
|
||
|
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
holder.ArgumentCount = len(holder.Arguments)
|
||
|
}
|
||
|
|
||
|
return holder
|
||
|
}
|