From 39e61887879d22b17de4112d7c3c619b150974d3 Mon Sep 17 00:00:00 2001 From: "diamondburned (Forefront)" Date: Sat, 25 Jan 2020 14:07:49 -0800 Subject: [PATCH] Bot: simplified Arguments of a CommandContext --- bot/arguments.go | 14 +++++++++----- bot/ctx_call.go | 18 +++++++++--------- bot/subcommand.go | 21 +++++++++------------ bot/subcommand_test.go | 10 ++-------- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/bot/arguments.go b/bot/arguments.go index ef8d6dd..59ed1d0 100644 --- a/bot/arguments.go +++ b/bot/arguments.go @@ -41,7 +41,7 @@ func (r *RawArguments) ParseContent(args []string) error { return nil } -func (r *RawArguments) Arg(n int) string { +func (r RawArguments) Arg(n int) string { if n < 0 || n >= len(r.Arguments) { return "" } @@ -49,7 +49,7 @@ func (r *RawArguments) Arg(n int) string { return r.Arguments[n] } -func (r *RawArguments) After(n int) string { +func (r RawArguments) After(n int) string { if n < 0 || n >= len(r.Arguments) { return "" } @@ -57,19 +57,23 @@ func (r *RawArguments) After(n int) string { return strings.Join(r.Arguments[n:], " ") } -func (r *RawArguments) String() string { +func (r RawArguments) String() string { return r.Command + " " + strings.Join(r.Arguments, " ") } -func (r *RawArguments) Length() int { +func (r RawArguments) Length() int { return len(r.Arguments) } // Argument is each argument in a method. type Argument struct { String string - Type reflect.Type + // Rule: pointer for structs, direct for primitives + Type reflect.Type + + // if nil, then manual fn argumentValueFn + manual reflect.Method } // nilV, only used to return an error diff --git a/bot/ctx_call.go b/bot/ctx_call.go index aee4545..d1c28a8 100644 --- a/bot/ctx_call.go +++ b/bot/ctx_call.go @@ -206,8 +206,14 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error { // Start converting var argv []reflect.Value + // Here's an edge case: when the handler takes no arguments, we allow that + // anyway, as they might've used the raw content. + if len(cmd.Arguments) == 0 { + goto Call + } + // Check manual parser - if cmd.parseType != nil { + if cmd.Arguments[0].fn == nil { if len(args[start:]) == 0 { return &ErrInvalidUsage{ Args: args, @@ -219,10 +225,10 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error { } // Create a zero value instance of this - v := reflect.New(cmd.parseType) + v := reflect.New(cmd.Arguments[0].Type) // Call the manual parse method - ret := cmd.parseMethod.Func.Call([]reflect.Value{ + ret := cmd.Arguments[0].manual.Func.Call([]reflect.Value{ v, reflect.ValueOf(args), }) @@ -237,12 +243,6 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error { goto Call } - // Here's an edge case: when the handler takes no arguments, we allow that - // anyway, as they might've used the raw content. - if len(cmd.Arguments) == 0 { - goto Call - } - // Not enough arguments given if len(args[start:]) != len(cmd.Arguments) { return &ErrInvalidUsage{ diff --git a/bot/subcommand.go b/bot/subcommand.go index 09ac54d..7a86284 100644 --- a/bot/subcommand.go +++ b/bot/subcommand.go @@ -70,11 +70,6 @@ type CommandContext struct { method reflect.Method Arguments []Argument - - // only for ParseContent interface - parseMethod reflect.Method - parseType reflect.Type - parseUsage string } // CanSetup is used for subcommands to change variables, such as Description. @@ -86,10 +81,6 @@ type CanSetup interface { } func (cctx *CommandContext) Usage() []string { - if cctx.parseType != nil { - return []string{cctx.parseUsage} - } - if len(cctx.Arguments) == 0 { return nil } @@ -333,9 +324,15 @@ func (sub *Subcommand) parseCommands() error { if t := methodT.In(1); t.Implements(typeIManP) { mt, _ := t.MethodByName("ParseContent") - command.parseMethod = mt - command.parseType = t.Elem() - command.parseUsage = t.String() + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + command.Arguments = []Argument{{ + String: t.String(), + Type: t, + manual: mt, + }} goto Done } diff --git a/bot/subcommand_test.go b/bot/subcommand_test.go index 56e0ff7..6d9ec94 100644 --- a/bot/subcommand_test.go +++ b/bot/subcommand_test.go @@ -49,11 +49,8 @@ func TestSubcommand(t *testing.T) { case "custom": foundCustom = true - if len(this.Arguments) > 0 { - t.Fatal("arguments should be 0 for custom") - } - if this.parseType == nil { - t.Fatal("custom has nil manualParse") + if len(this.Arguments) != 1 { + t.Fatal("arguments should be 1 for custom") } case "noArgs": @@ -61,9 +58,6 @@ func TestSubcommand(t *testing.T) { if len(this.Arguments) != 0 { t.Fatal("expected 0 arguments, got non-zero") } - if this.parseType != nil { - t.Fatal("unexpected parseType") - } case "noop", "getCounter": // Found, but whatever