package commands import "errors" type CommandHolder struct { Name string Usage string Handler CommandHandler Permission int Arguments map[string]*CommandArgument ArgumentCount int RequiredArgumentCount int } type CommandArgument struct { Index int Name string Required bool Type int } func (c *CommandHolder) Call(ctx *CommandContext) { ctx.holder = c if c.ArgumentCount > 0 { // Arguments are cached, construct usage if err := c.Validate(ctx); err != nil { if err == UsageError { ctx.Reply("Usage: " + ctx.Prefix + c.Usage) } else { ctx.Reply(err.Error()) } return } } // Use a goroutine to avoid any blocking operations c.Handler(ctx) } var ( UsageError = errors.New("usage") ) func (c *CommandHolder) Validate(ctx *CommandContext) error { if ctx.ArgumentCount < c.RequiredArgumentCount { return UsageError } var argValue string for _, arg := range c.Arguments { if ctx.ArgumentCount < arg.Index+1 { break } if !arg.Required { continue } argValue = ctx.Arguments[arg.Index] if argValue == "" { return errors.New("The " + arg.Name + " argument is required.") } } return nil }