mirror of
https://github.com/diamondburned/arikawa.git
synced 2025-11-22 12:33:38 +00:00
Bot: Added variadic arguments support
This commit is contained in:
parent
af682d3f35
commit
3b903dce68
|
|
@ -93,7 +93,7 @@ func (c *Content) CustomParse(content string) error {
|
||||||
type Argument struct {
|
type Argument struct {
|
||||||
String string
|
String string
|
||||||
// Rule: pointer for structs, direct for primitives
|
// Rule: pointer for structs, direct for primitives
|
||||||
Type reflect.Type
|
rtype reflect.Type
|
||||||
|
|
||||||
// indicates if the type is referenced, meaning it's a pointer but not the
|
// indicates if the type is referenced, meaning it's a pointer but not the
|
||||||
// original call.
|
// original call.
|
||||||
|
|
@ -105,6 +105,10 @@ type Argument struct {
|
||||||
custom *reflect.Method
|
custom *reflect.Method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Argument) Type() reflect.Type {
|
||||||
|
return a.rtype
|
||||||
|
}
|
||||||
|
|
||||||
var ShellwordsEscaper = strings.NewReplacer(
|
var ShellwordsEscaper = strings.NewReplacer(
|
||||||
"\\", "\\\\",
|
"\\", "\\\\",
|
||||||
)
|
)
|
||||||
|
|
@ -116,7 +120,12 @@ var ParseArgs = func(args string) ([]string, error) {
|
||||||
// nilV, only used to return an error
|
// nilV, only used to return an error
|
||||||
var nilV = reflect.Value{}
|
var nilV = reflect.Value{}
|
||||||
|
|
||||||
func getArgumentValueFn(t reflect.Type) (*Argument, error) {
|
func getArgumentValueFn(t reflect.Type, variadic bool) (*Argument, error) {
|
||||||
|
// Allow array types if varidic is true.
|
||||||
|
if variadic && t.Kind() == reflect.Slice {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
var typeI = t
|
var typeI = t
|
||||||
var ptr = false
|
var ptr = false
|
||||||
|
|
||||||
|
|
@ -152,7 +161,7 @@ func getArgumentValueFn(t reflect.Type) (*Argument, error) {
|
||||||
|
|
||||||
return &Argument{
|
return &Argument{
|
||||||
String: fromUsager(typeI),
|
String: fromUsager(typeI),
|
||||||
Type: typeI,
|
rtype: typeI,
|
||||||
pointer: ptr,
|
pointer: ptr,
|
||||||
fn: avfn,
|
fn: avfn,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
@ -166,17 +175,13 @@ func getArgumentValueFn(t reflect.Type) (*Argument, error) {
|
||||||
return reflect.ValueOf(s), nil
|
return reflect.ValueOf(s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
case reflect.Int, reflect.Int8,
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
|
|
||||||
fn = func(s string) (reflect.Value, error) {
|
fn = func(s string) (reflect.Value, error) {
|
||||||
i, err := strconv.ParseInt(s, 10, 64)
|
i, err := strconv.ParseInt(s, 10, 64)
|
||||||
return quickRet(i, err, t)
|
return quickRet(i, err, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
case reflect.Uint, reflect.Uint8,
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
|
|
||||||
fn = func(s string) (reflect.Value, error) {
|
fn = func(s string) (reflect.Value, error) {
|
||||||
u, err := strconv.ParseUint(s, 10, 64)
|
u, err := strconv.ParseUint(s, 10, 64)
|
||||||
return quickRet(u, err, t)
|
return quickRet(u, err, t)
|
||||||
|
|
@ -196,7 +201,7 @@ func getArgumentValueFn(t reflect.Type) (*Argument, error) {
|
||||||
case "False", "FALSE", "false", "F", "f", "no", "n", "N", "0":
|
case "False", "FALSE", "false", "F", "f", "no", "n", "N", "0":
|
||||||
return reflect.ValueOf(false), nil
|
return reflect.ValueOf(false), nil
|
||||||
default:
|
default:
|
||||||
return nilV, errors.New("invalid bool [true/false]")
|
return nilV, errors.New("invalid bool [true|false]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -207,7 +212,7 @@ func getArgumentValueFn(t reflect.Type) (*Argument, error) {
|
||||||
|
|
||||||
return &Argument{
|
return &Argument{
|
||||||
String: t.String(),
|
String: t.String(),
|
||||||
Type: t,
|
rtype: t,
|
||||||
fn: fn,
|
fn: fn,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -232,9 +237,11 @@ func fromUsager(typeI reflect.Type) string {
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("BUG: type IUsager does not implement Usage")
|
panic("BUG: type IUsager does not implement Usage")
|
||||||
}
|
}
|
||||||
|
|
||||||
vs := mt.Func.Call([]reflect.Value{reflect.New(typeI.Elem())})
|
vs := mt.Func.Call([]reflect.Value{reflect.New(typeI.Elem())})
|
||||||
return vs[0].String()
|
return vs[0].String()
|
||||||
}
|
}
|
||||||
|
|
||||||
s := strings.Split(typeI.String(), ".")
|
s := strings.Split(typeI.String(), ".")
|
||||||
return s[len(s)-1]
|
return s[len(s)-1]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,15 +27,14 @@ func TestArguments(t *testing.T) {
|
||||||
testArgs(t, mockParse("testString"), "testString")
|
testArgs(t, mockParse("testString"), "testString")
|
||||||
testArgs(t, *mockParse("testString"), "testString")
|
testArgs(t, *mockParse("testString"), "testString")
|
||||||
|
|
||||||
_, err := getArgumentValueFn(reflect.TypeOf(struct{}{}))
|
_, err := getArgumentValueFn(reflect.TypeOf(struct{}{}), false)
|
||||||
if !strings.HasPrefix(err.Error(), "invalid type: ") {
|
if !strings.HasPrefix(err.Error(), "invalid type: ") {
|
||||||
t.Fatal("Unexpected error:", err)
|
t.Fatal("Unexpected error:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testArgs(t *testing.T, expect interface{}, input string) {
|
func testArgs(t *testing.T, expect interface{}, input string) {
|
||||||
f, err := getArgumentValueFn(reflect.TypeOf(expect))
|
f, err := getArgumentValueFn(reflect.TypeOf(expect), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Failed to get argument value function:", err)
|
t.Fatal("Failed to get argument value function:", err)
|
||||||
}
|
}
|
||||||
|
|
@ -49,3 +48,23 @@ func testArgs(t *testing.T, expect interface{}, input string) {
|
||||||
t.Fatal("Value :", v, "\nExpects:", expect)
|
t.Fatal("Value :", v, "\nExpects:", expect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used for ctx_test.go
|
||||||
|
|
||||||
|
type customManualParsed struct {
|
||||||
|
args []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *customManualParsed) ParseContent(args []string) error {
|
||||||
|
c.args = args
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type customParsed struct {
|
||||||
|
parsed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *customParsed) Parse(string) error {
|
||||||
|
c.parsed = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
||||||
// Check manual or parser
|
// Check manual or parser
|
||||||
if cmd.Arguments[0].fn == nil {
|
if cmd.Arguments[0].fn == nil {
|
||||||
// Create a zero value instance of this:
|
// Create a zero value instance of this:
|
||||||
v := reflect.New(cmd.Arguments[0].Type)
|
v := reflect.New(cmd.Arguments[0].rtype)
|
||||||
ret := []reflect.Value{}
|
ret := []reflect.Value{}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|
@ -313,35 +313,78 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
||||||
goto Call
|
goto Call
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not enough arguments given
|
// Argument count check.
|
||||||
if delta := len(args[start:]) - len(cmd.Arguments); delta != 0 {
|
if argdelta := len(args[start:]) - len(cmd.Arguments); argdelta != 0 {
|
||||||
var err = "Not enough arguments given"
|
var err error // no err if nil
|
||||||
if delta > 0 {
|
|
||||||
err = "Too many arguments given"
|
switch {
|
||||||
|
// If there aren't enough arguments given.
|
||||||
|
case argdelta < 0:
|
||||||
|
err = ErrNotEnoughArgs
|
||||||
|
|
||||||
|
// If there are too many arguments, then check if the command supports
|
||||||
|
// variadic arguments. We already did a length check above.
|
||||||
|
case argdelta > 0 && !cmd.Variadic:
|
||||||
|
// If it's not variadic, then we can't accept it.
|
||||||
|
err = ErrTooManyArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ErrInvalidUsage{
|
|
||||||
Args: args,
|
|
||||||
Index: len(args) - 1,
|
|
||||||
Err: err,
|
|
||||||
Ctx: cmd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
argv = make([]reflect.Value, len(cmd.Arguments))
|
|
||||||
|
|
||||||
for i := start; i < len(args); i++ {
|
|
||||||
v, err := cmd.Arguments[i-start].fn(args[i])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrInvalidUsage{
|
return &ErrInvalidUsage{
|
||||||
|
Prefix: pf,
|
||||||
|
Args: args,
|
||||||
|
Index: len(args) - 1,
|
||||||
|
Wrap: err,
|
||||||
|
Ctx: cmd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a new slice the length of function arguments.
|
||||||
|
argv = make([]reflect.Value, len(cmd.Arguments))
|
||||||
|
|
||||||
|
for i := 0; i < len(argv); i++ {
|
||||||
|
v, err := cmd.Arguments[i].fn(args[start+i])
|
||||||
|
if err != nil {
|
||||||
|
return &ErrInvalidUsage{
|
||||||
|
Prefix: pf,
|
||||||
Args: args,
|
Args: args,
|
||||||
Index: i,
|
Index: i,
|
||||||
Err: err.Error(),
|
Wrap: err,
|
||||||
Ctx: cmd,
|
Ctx: cmd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argv[i-start] = v
|
argv[i] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the rest with variadic arguments. Go's reflect states that varidic
|
||||||
|
// parameters will automatically be copied, which is good.
|
||||||
|
if len(args) > len(argv) {
|
||||||
|
// The location to continue parsing from args.
|
||||||
|
argc := len(argv)
|
||||||
|
// Allocate a new slice to append into. We start 1-off from the start,
|
||||||
|
// as the first argument of the variadic slice is already parsed.
|
||||||
|
vars := make([]reflect.Value, len(args)-len(argv)-1)
|
||||||
|
last := cmd.Arguments[len(cmd.Arguments)-1]
|
||||||
|
|
||||||
|
// Continue the above loop, where i stops before len(argv).
|
||||||
|
for i := 0; i < len(vars); i++ {
|
||||||
|
v, err := last.fn(args[argc+i+1])
|
||||||
|
if err != nil {
|
||||||
|
return &ErrInvalidUsage{
|
||||||
|
Prefix: pf,
|
||||||
|
Args: args,
|
||||||
|
Index: i,
|
||||||
|
Wrap: err,
|
||||||
|
Ctx: cmd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vars[i] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
argv = append(argv, vars...)
|
||||||
}
|
}
|
||||||
|
|
||||||
Call:
|
Call:
|
||||||
|
|
@ -426,10 +469,12 @@ func callWith(
|
||||||
caller reflect.Value,
|
caller reflect.Value,
|
||||||
ev interface{}, values ...reflect.Value) (interface{}, error) {
|
ev interface{}, values ...reflect.Value) (interface{}, error) {
|
||||||
|
|
||||||
return errorReturns(caller.Call(append(
|
values = append(
|
||||||
[]reflect.Value{reflect.ValueOf(ev)},
|
[]reflect.Value{reflect.ValueOf(ev)},
|
||||||
values...,
|
values...,
|
||||||
)))
|
)
|
||||||
|
|
||||||
|
return errorReturns(caller.Call(values))
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorReturns(returns []reflect.Value) (interface{}, error) {
|
func errorReturns(returns []reflect.Value) (interface{}, error) {
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,21 @@ func (t *testCommands) GetCounter(_ *gateway.MessageCreateEvent) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testCommands) Send(_ *gateway.MessageCreateEvent, arg string) error {
|
func (t *testCommands) Send(_ *gateway.MessageCreateEvent, args ...string) error {
|
||||||
t.Return <- arg
|
t.Return <- args
|
||||||
return errors.New("oh no")
|
return errors.New("oh no")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testCommands) Custom(_ *gateway.MessageCreateEvent, c *customParseable) error {
|
func (t *testCommands) Custom(_ *gateway.MessageCreateEvent, c *customManualParsed) error {
|
||||||
t.Return <- c.args
|
t.Return <- c.args
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *testCommands) Variadic(_ *gateway.MessageCreateEvent, c ...*customParsed) error {
|
||||||
|
t.Return <- c[len(c)-1]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *testCommands) NoArgs(_ *gateway.MessageCreateEvent) error {
|
func (t *testCommands) NoArgs(_ *gateway.MessageCreateEvent) error {
|
||||||
return errors.New("passed")
|
return errors.New("passed")
|
||||||
}
|
}
|
||||||
|
|
@ -52,15 +57,6 @@ func (t *testCommands) OnTyping(_ *gateway.TypingStartEvent) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type customParseable struct {
|
|
||||||
args []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *customParseable) ParseContent(args []string) error {
|
|
||||||
c.args = args
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewContext(t *testing.T) {
|
func TestNewContext(t *testing.T) {
|
||||||
var state = &state.State{
|
var state = &state.State{
|
||||||
Store: state.NewDefaultStore(nil),
|
Store: state.NewDefaultStore(nil),
|
||||||
|
|
@ -181,12 +177,17 @@ func TestContext(t *testing.T) {
|
||||||
// Set a custom prefix
|
// Set a custom prefix
|
||||||
ctx.HasPrefix = NewPrefix("~")
|
ctx.HasPrefix = NewPrefix("~")
|
||||||
|
|
||||||
if err := testReturn("test", "~send test"); err.Error() != "oh no" {
|
var (
|
||||||
|
strings = "hacka doll no. 3"
|
||||||
|
expects = []string{"hacka", "doll", "no.", "3"}
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := testReturn(expects, "~send "+strings); err.Error() != "oh no" {
|
||||||
t.Fatal("Unexpected error:", err)
|
t.Fatal("Unexpected error:", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("call command custom parser", func(t *testing.T) {
|
t.Run("call command custom manual parser", func(t *testing.T) {
|
||||||
ctx.HasPrefix = NewPrefix("!")
|
ctx.HasPrefix = NewPrefix("!")
|
||||||
expects := []string{"custom", "arg1", ":)"}
|
expects := []string{"custom", "arg1", ":)"}
|
||||||
|
|
||||||
|
|
@ -195,6 +196,15 @@ func TestContext(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("call command custom variadic parser", func(t *testing.T) {
|
||||||
|
ctx.HasPrefix = NewPrefix("!")
|
||||||
|
expects := &customParsed{true}
|
||||||
|
|
||||||
|
if err := testReturn(expects, "!variadic bruh moment"); err != nil {
|
||||||
|
t.Fatal("Unexpected call error:", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
testMessage := func(content string) error {
|
testMessage := func(content string) error {
|
||||||
// Mock a messageCreate event
|
// Mock a messageCreate event
|
||||||
m := &gateway.MessageCreateEvent{
|
m := &gateway.MessageCreateEvent{
|
||||||
|
|
|
||||||
24
bot/error.go
24
bot/error.go
|
|
@ -1,10 +1,12 @@
|
||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ErrUnknownCommand struct {
|
type ErrUnknownCommand struct {
|
||||||
|
Prefix string
|
||||||
Command string
|
Command string
|
||||||
Parent string
|
Parent string
|
||||||
|
|
||||||
|
|
@ -18,7 +20,7 @@ func (err *ErrUnknownCommand) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var UnknownCommandString = func(err *ErrUnknownCommand) string {
|
var UnknownCommandString = func(err *ErrUnknownCommand) string {
|
||||||
var header = "Unknown command: "
|
var header = "Unknown command: " + err.Prefix
|
||||||
if err.Parent != "" {
|
if err.Parent != "" {
|
||||||
header += err.Parent + " " + err.Command
|
header += err.Parent + " " + err.Command
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -28,10 +30,16 @@ var UnknownCommandString = func(err *ErrUnknownCommand) string {
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrTooManyArgs = errors.New("Too many arguments given")
|
||||||
|
ErrNotEnoughArgs = errors.New("Not enough arguments given")
|
||||||
|
)
|
||||||
|
|
||||||
type ErrInvalidUsage struct {
|
type ErrInvalidUsage struct {
|
||||||
|
Prefix string
|
||||||
Args []string
|
Args []string
|
||||||
Index int
|
Index int
|
||||||
Err string
|
Wrap error
|
||||||
|
|
||||||
// TODO: usage generator?
|
// TODO: usage generator?
|
||||||
// Here, as a reminder
|
// Here, as a reminder
|
||||||
|
|
@ -42,9 +50,13 @@ func (err *ErrInvalidUsage) Error() string {
|
||||||
return InvalidUsageString(err)
|
return InvalidUsageString(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err *ErrInvalidUsage) Unwrap() error {
|
||||||
|
return err.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
var InvalidUsageString = func(err *ErrInvalidUsage) string {
|
var InvalidUsageString = func(err *ErrInvalidUsage) string {
|
||||||
if err.Index == 0 {
|
if err.Index == 0 {
|
||||||
return "Invalid usage, error: " + err.Err
|
return "Invalid usage, error: " + err.Wrap.Error() + "."
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(err.Args) == 0 {
|
if len(err.Args) == 0 {
|
||||||
|
|
@ -52,6 +64,8 @@ var InvalidUsageString = func(err *ErrInvalidUsage) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
body := "Invalid usage at " +
|
body := "Invalid usage at " +
|
||||||
|
// Write the prefix.
|
||||||
|
err.Prefix +
|
||||||
// Write the first part
|
// Write the first part
|
||||||
strings.Join(err.Args[:err.Index], " ") +
|
strings.Join(err.Args[:err.Index], " ") +
|
||||||
// Write the wrong part
|
// Write the wrong part
|
||||||
|
|
@ -59,8 +73,8 @@ var InvalidUsageString = func(err *ErrInvalidUsage) string {
|
||||||
// Write the last part
|
// Write the last part
|
||||||
strings.Join(err.Args[err.Index+1:], " ")
|
strings.Join(err.Args[err.Index+1:], " ")
|
||||||
|
|
||||||
if err.Err != "" {
|
if err.Wrap != nil {
|
||||||
body += "\nError: " + err.Err
|
body += "\nError: " + err.Wrap.Error() + "."
|
||||||
}
|
}
|
||||||
|
|
||||||
return body
|
return body
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,9 @@ type CommandContext struct {
|
||||||
// Hidden is true if the method has a hidden nameflag.
|
// Hidden is true if the method has a hidden nameflag.
|
||||||
Hidden bool
|
Hidden bool
|
||||||
|
|
||||||
|
// Variadic is true if the function is a variadic one.
|
||||||
|
Variadic bool
|
||||||
|
|
||||||
value reflect.Value // Func
|
value reflect.Value // Func
|
||||||
event reflect.Type // gateway.*Event
|
event reflect.Type // gateway.*Event
|
||||||
method reflect.Method
|
method reflect.Method
|
||||||
|
|
@ -392,6 +395,7 @@ func (sub *Subcommand) parseCommands() error {
|
||||||
method: sub.ptrType.Method(i),
|
method: sub.ptrType.Method(i),
|
||||||
value: method,
|
value: method,
|
||||||
event: methodT.In(0), // parse event
|
event: methodT.In(0), // parse event
|
||||||
|
Variadic: methodT.IsVariadic(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the method name
|
// Parse the method name
|
||||||
|
|
@ -460,7 +464,7 @@ func (sub *Subcommand) parseCommands() error {
|
||||||
|
|
||||||
command.Arguments = []Argument{{
|
command.Arguments = []Argument{{
|
||||||
String: t.String(),
|
String: t.String(),
|
||||||
Type: t,
|
rtype: t,
|
||||||
pointer: ptr,
|
pointer: ptr,
|
||||||
custom: &mt,
|
custom: &mt,
|
||||||
}}
|
}}
|
||||||
|
|
@ -478,7 +482,7 @@ func (sub *Subcommand) parseCommands() error {
|
||||||
|
|
||||||
command.Arguments = []Argument{{
|
command.Arguments = []Argument{{
|
||||||
String: t.String(),
|
String: t.String(),
|
||||||
Type: t,
|
rtype: t,
|
||||||
pointer: ptr,
|
pointer: ptr,
|
||||||
manual: &mt,
|
manual: &mt,
|
||||||
}}
|
}}
|
||||||
|
|
@ -491,7 +495,7 @@ func (sub *Subcommand) parseCommands() error {
|
||||||
// Fill up arguments
|
// Fill up arguments
|
||||||
for i := 1; i < numArgs; i++ {
|
for i := 1; i < numArgs; i++ {
|
||||||
t := methodT.In(i)
|
t := methodT.In(i)
|
||||||
a, err := getArgumentValueFn(t)
|
a, err := getArgumentValueFn(t, command.Variadic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Error parsing argument "+t.String())
|
return errors.Wrap(err, "Error parsing argument "+t.String())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ func TestSubcommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!! CHANGE ME
|
// !!! CHANGE ME
|
||||||
if len(sub.Commands) != 5 {
|
if len(sub.Commands) != 6 {
|
||||||
t.Fatal("invalid ctx.commands len", len(sub.Commands))
|
t.Fatal("invalid ctx.commands len", len(sub.Commands))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,11 +57,8 @@ func TestSubcommand(t *testing.T) {
|
||||||
t.Fatal("expected 0 arguments, got non-zero")
|
t.Fatal("expected 0 arguments, got non-zero")
|
||||||
}
|
}
|
||||||
|
|
||||||
case "noop", "getCounter":
|
case "noop", "getCounter", "variadic":
|
||||||
// Found, but whatever
|
// Found, but whatever
|
||||||
|
|
||||||
default:
|
|
||||||
t.Fatal("Unexpected command:", this.Command)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.event != typeMessageCreate {
|
if this.event != typeMessageCreate {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue