Bot: simplified Arguments of a CommandContext
This commit is contained in:
parent
0c8c43d3f5
commit
39e6188787
|
@ -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
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue