Bot: Added a Prefixer API which breaks the old Prefix string API

This commit is contained in:
diamondburned (Forefront) 2020-04-06 13:25:42 -07:00
parent 58f0feb143
commit 09ae9fbb07
7 changed files with 50 additions and 46 deletions

View File

@ -18,7 +18,7 @@ func main() {
commands := &Bot{}
wait, err := bot.Start(token, commands, func(ctx *bot.Context) error {
ctx.Prefix = "!"
ctx.HasPrefix = bot.NewPrefix("!", "~")
// Subcommand demo, but this can be in another package.
ctx.MustRegisterSubcommand(&Debug{})

View File

@ -29,8 +29,6 @@ func main() {
log.Fatalln("Failed to connect:", err)
}
defer s.Close()
u, err := s.Me()
if err != nil {
log.Fatalln("Failed to get myself:", err)
@ -38,7 +36,7 @@ func main() {
log.Println("Started as", u.Username)
// Block until a fatal error or SIGINT.
// Block until a fatal error or SIGINT. Wait also calls Close().
if err := s.Wait(); err != nil {
log.Fatalln("Gateway fatal error:", err)
}

View File

@ -39,8 +39,6 @@ func main() {
log.Fatalln("Failed to connect:", err)
}
defer s.Close()
u, err := s.Me()
if err != nil {
log.Fatalln("Failed to get myself:", err)
@ -48,7 +46,7 @@ func main() {
log.Println("Started as", u.Username)
// Block until a fatal error or SIGINT.
// Block until a fatal error or SIGINT. Wait also calls Close().
if err := s.Wait(); err != nil {
log.Fatalln("Gateway fatal error:", err)
}

View File

@ -12,6 +12,23 @@ import (
"github.com/pkg/errors"
)
// Prefixer checks a message if it starts with the desired prefix. By default,
// NewPrefix() is used.
type Prefixer func(*gateway.MessageCreateEvent) (prefix string, ok bool)
// NewPrefix creates a simple prefix checker using strings. As the default
// prefix is "!", the function is called as NewPrefix("!").
func NewPrefix(prefixes ...string) Prefixer {
return func(msg *gateway.MessageCreateEvent) (string, bool) {
for _, prefix := range prefixes {
if strings.HasPrefix(msg.Content, prefix) {
return prefix, true
}
}
return "", false
}
}
// TODO: add variadic arguments
// Context is the bot state for commands and subcommands.
@ -56,8 +73,9 @@ type Context struct {
// Descriptive help body
Description string
// The prefix for commands
Prefix string
// Called to check a message's prefix. The default prefix is "!". Refer to
// NewPrefix().
HasPrefix Prefixer
// FormatError formats any errors returned by anything, including the method
// commands or the reflect functions. This also includes invalid usage
@ -152,7 +170,7 @@ func New(s *state.State, cmd interface{}) (*Context, error) {
ctx := &Context{
Subcommand: c,
State: s,
Prefix: "~",
HasPrefix: NewPrefix("~"),
FormatError: func(err error) string {
// Escape all pings, including @everyone.
return strings.Replace(err.Error(), "@", "@\u200b", -1)
@ -176,6 +194,8 @@ func (ctx *Context) Wait() error {
return ctx.Session.Wait()
}
// Subcommands returns the slice of subcommands. To add subcommands, use
// RegisterSubcommand().
func (ctx *Context) Subcommands() []*Subcommand {
// Getter is not useless, refer to the struct doc for reason.
return ctx.subcommands
@ -348,7 +368,7 @@ func (ctx *Context) help(hideAdmin bool) string {
continue
}
help.WriteString(indent + ctx.Prefix + cmd.Command)
help.WriteString(indent + cmd.Command)
switch {
case len(cmd.Usage()) > 0:
@ -364,7 +384,7 @@ func (ctx *Context) help(hideAdmin bool) string {
var subcommands = ctx.Subcommands()
for _, sub := range subcommands {
if help := sub.Help(ctx.Prefix, indent, hideAdmin); help != "" {
if help := sub.Help(indent, hideAdmin); help != "" {
subHelp.WriteString(help)
}
}

View File

@ -114,13 +114,13 @@ func (ctx *Context) callCmd(ev interface{}) error {
func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
// check if prefix
if !strings.HasPrefix(mc.Content, ctx.Prefix) {
// not a command, ignore
pf, ok := ctx.HasPrefix(mc)
if !ok {
return nil
}
// trim the prefix before splitting, this way multi-words prefices work
content := mc.Content[len(ctx.Prefix):]
content := mc.Content[len(pf):]
if content == "" {
return nil // just the prefix only
@ -197,7 +197,6 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
return &ErrUnknownCommand{
Command: args[1],
Parent: args[0],
Prefix: ctx.Prefix,
ctx: s.Commands,
}
}
@ -213,7 +212,6 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
return &ErrUnknownCommand{
Command: args[0],
Prefix: ctx.Prefix,
ctx: ctx.Commands,
}
}
@ -292,11 +290,10 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
}
return &ErrInvalidUsage{
Args: args,
Prefix: ctx.Prefix,
Index: len(args) - 1,
Err: err,
Ctx: cmd,
Args: args,
Index: len(args) - 1,
Err: err,
Ctx: cmd,
}
}
@ -306,11 +303,10 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
v, err := cmd.Arguments[i-start].fn(args[i])
if err != nil {
return &ErrInvalidUsage{
Args: args,
Prefix: ctx.Prefix,
Index: i,
Err: err.Error(),
Ctx: cmd,
Args: args,
Index: i,
Err: err.Error(),
Ctx: cmd,
}
}

View File

@ -8,8 +8,6 @@ type ErrUnknownCommand struct {
Command string
Parent string
Prefix string
// TODO: list available commands?
// Here, as a reminder
ctx []*CommandContext
@ -20,7 +18,7 @@ func (err *ErrUnknownCommand) Error() string {
}
var UnknownCommandString = func(err *ErrUnknownCommand) string {
var header = "Unknown command: " + err.Prefix
var header = "Unknown command: "
if err.Parent != "" {
header += err.Parent + " " + err.Command
} else {
@ -31,9 +29,7 @@ var UnknownCommandString = func(err *ErrUnknownCommand) string {
}
type ErrInvalidUsage struct {
Args []string
Prefix string
Args []string
Index int
Err string
@ -55,16 +51,13 @@ var InvalidUsageString = func(err *ErrInvalidUsage) string {
return "Missing arguments. Refer to help."
}
body := "Invalid usage at " + err.Prefix
// Write the first part
body += strings.Join(err.Args[:err.Index], " ")
// Write the wrong part
body += " __" + err.Args[err.Index] + "__ "
// Write the last part
body += strings.Join(err.Args[err.Index+1:], " ")
body := "Invalid usage at " +
// Write the first part
strings.Join(err.Args[:err.Index], " ") +
// Write the wrong part
" __" + err.Args[err.Index] + "__ " +
// Write the last part
strings.Join(err.Args[err.Index+1:], " ")
if err.Err != "" {
body += "\nError: " + err.Err

View File

@ -173,7 +173,7 @@ func (sub *Subcommand) ChangeCommandInfo(methodName, cmd, desc string) bool {
return false
}
func (sub *Subcommand) Help(prefix, indent string, hideAdmin bool) string {
func (sub *Subcommand) Help(indent string, hideAdmin bool) string {
if sub.Flag.Is(AdminOnly) && hideAdmin {
return ""
}
@ -205,8 +205,7 @@ func (sub *Subcommand) Help(prefix, indent string, hideAdmin bool) string {
continue
}
commands += indent + indent +
prefix + sub.Command + " " + cmd.Command
commands += indent + indent + sub.Command + " " + cmd.Command
switch {
case len(cmd.Usage()) > 0: