rfrouter

package module
v0.0.0-...-b54cad6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2019 License: Apache-2.0 Imports: 8 Imported by: 0

README

rfrouter

Proof-of-concept

Usage

var token = "Bot 123456abcxyz"
var cmds  = Commands{}

c, err := rfrouter.StartBot(token, &cmds,
	func(ctx *rfrouter.Context) error {
		// Set the prefix
		ctx.Prefix = "~"

		// Set the descriptions
		ctx.Name = "bot example"
		ctx.Description = "https://git.sr.ht/~diamondburned/rfrouter"

		return err
	},
)

if err != nil {
	log.Fatalln("Failed to start the bot:", err)
}

defer c()
type Commands struct {
	// Field name can be anything, but this field must be provided
	Ctx *Context
}

func (c *Commands) Send(msg *discordgo.MessageCreate, arg string) error {
	_, err := c.Ctx.Send(msg.ChannelID, "You sent: " + arg)
	return err
}

Features

  • Automatic command routing from Go methods
  • Implicit name conversion between strings and method names
  • Mapping Go arguments from strings
  • Pluggable parsers and arguments
  • Subcommands allow for plug-ins
  • Help page generation

Non-features

  • Descriptions for commands: impossible (or otherwise impractical) without any form of code parsing.

Some extra features nobody cares about

Interfaces
Parseable
// Parseable implements a Parse(string) method for data structures that can be
// used as arguments.
type Parseable interface {
	Parse(string) error
}
Example (refer to extras/arguments/emoji.go)
ManualParseable
// ManualParseable implements a ParseContent(string) method. If the library sees
// this for an argument, it will send all of the arguments (including the
// command) into the method. If used, this should be the only argument followed
// after the Message Create event. Any more and the router will ignore.
type ManualParseable interface {
	// $0 will have its prefix trimmed.
	ParseContent([]string) error
}
Example (refer to extras/arguments/flag.go)
Usager
// Usager is optionally used to override the generated usage for either an
// argument, or multiple (using ManualParseable).
type Usager interface {
	Usage() string
}
Example (refer to extras/arguments/mention.go)

Documentation

Index

Constants

View Source
const FlagSeparator = 'ー'

Variables

View Source
var ParseArgs = func(args string) ([]string, error) {

	r := csv.NewReader(strings.NewReader(args))
	r.Comma = ' '

	return r.Read()
}

Functions

func MemberPermissions

func MemberPermissions(guild *discordgo.Guild, channel *discordgo.Channel,
	member *discordgo.Member) (apermissions int)

Why this isn't exported, I have no idea.

func StartBot

func StartBot(token string, cmd interface{},
	opts func(*Context) error) (stop func() error, err error)

StartBot quickly starts a bot with the given command. It will prepend "Bot" into the token automatically. Refer to example/ for usage.

Types

type CommandContext

type CommandContext struct {
	Description string
	Flag        NameFlag
	// contains filtered or unexported fields
}

CommandContext is an internal struct containing fields to make this library work. As such, they're all unexported. Description, however, is exported for editing, and may be used to generate more informative help messages.

func (*CommandContext) Name

func (cctx *CommandContext) Name() string

func (*CommandContext) Usage

func (cctx *CommandContext) Usage() []string

type Context

type Context struct {
	*Subcommand
	*discordgo.Session

	// Descriptive (but optional) bot name
	Name string

	// Descriptive help body
	Description string

	// The prefix for commands
	Prefix string

	// FormatError formats any errors returned by anything, including the method
	// commands or the reflect functions. This also includes invalid usage
	// errors or unknown command errors. Returning an empty string means
	// ignoring the error.
	FormatError func(error) string

	// ErrorLogger logs any error that anything makes and the library can't
	// reply to the client. This includes any event callback errors that aren't
	// Message Create.
	ErrorLogger func(error)

	// ReplyError when true replies to the user the error.
	ReplyError bool

	// Subcommands contains all the registered subcommands.
	Subcommands []*Subcommand
}

func New

func New(s *discordgo.Session, cmd interface{}) (*Context, error)

New makes a new context with a "~" as the prefix. cmds must be a pointer to a struct with a *Context field. Example:

type Commands struct {
    Ctx *Context
}

cmds := &Commands{}
c, err := rfrouter.New(session, cmds)

Commands' exported methods will all be used as commands. Messages are parsed with its first argument (the command) mapped accordingly to c.MapName, which capitalizes the first letter automatically to reflect the exported method name.

The default prefix is "~", which means commands must start with "~" followed by the command name in the first argument, else it will be ignored.

c.Start() should be called afterwards to actually handle incoming events.

func (*Context) Call

func (ctx *Context) Call(event interface{}) error

Call should only be used if you know what you're doing.

func (*Context) Channel

func (ctx *Context) Channel(channelID string) (*discordgo.Channel, error)

Channel returns the channel, adding it to the State.

func (*Context) Help

func (ctx *Context) Help() string

Help generates one. This function is used more for reference than an actual help message. As such, it only uses exported fields or methods.

func (*Context) Member

func (ctx *Context) Member(guildID, memberID string) (*discordgo.Member, error)

Member returns the member, adding it to the State.

func (*Context) RegisterSubcommand

func (ctx *Context) RegisterSubcommand(cmd interface{}) (*Subcommand, error)

func (*Context) Reply

func (ctx *Context) Reply(m *discordgo.Message, reply string) error

Reply mentions the user when sending the message.

func (*Context) Role

func (ctx *Context) Role(guildID, roleID string) (*discordgo.Role, error)

Role returns the role, adding it to the State.

func (*Context) Send

func (ctx *Context) Send(channelID string, content interface{}) (err error)

Send sends a string, an embed pointer or a MessageSend pointer. Any other type given will panic.

func (*Context) Start

func (ctx *Context) Start() func()

Start adds itself into the discordgo Session handlers. This needs to be run. The returned function is a delete function, which removes itself from the Session handlers.

func (*Context) UserPermissions

func (ctx *Context) UserPermissions(channelID, userID string,
) (apermissions int, err error)

UserPermissions but userID is after channelID.

type Descriptor

type Descriptor interface {
	Description() string
}

Descriptor is optionally used to set the Description of a command context.

type ErrInvalidUsage

type ErrInvalidUsage struct {
	Args   []string
	Prefix string

	Index int
	Err   string
	// contains filtered or unexported fields
}

func (*ErrInvalidUsage) Error

func (err *ErrInvalidUsage) Error() string

type ErrUnknownCommand

type ErrUnknownCommand struct {
	Command string
	Parent  string

	Prefix string
	// contains filtered or unexported fields
}

func (*ErrUnknownCommand) Error

func (err *ErrUnknownCommand) Error() string

type ManualParseable

type ManualParseable interface {
	// $0 will have its prefix trimmed.
	ParseContent([]string) error
}

ManaulParseable implements a ParseContent(string) method. If the library sees this for an argument, it will send all of the arguments (including the command) into the method. If used, this should be the only argument followed after the Message Create event. Any more and the router will ignore.

type NameFlag

type NameFlag uint64
const (
	None NameFlag = 1 << iota

	Raw       // R
	AdminOnly // A
)

func ParseFlag

func ParseFlag(name string) (NameFlag, string)

func (NameFlag) Is

func (f NameFlag) Is(flag NameFlag) bool

type Namer

type Namer interface {
	Name() string
}

Namer is optionally used to override the command context's name.

type Parseable

type Parseable interface {
	Parse(string) error
}

Parseable implements a Parse(string) method for data structures that can be used as arguments.

type RawArguments

type RawArguments struct {
	Arguments []string
}

func (*RawArguments) ParseContent

func (r *RawArguments) ParseContent(args []string) error

type Subcommand

type Subcommand struct {
	Description string

	// Commands contains all the registered command contexts.
	Commands []*CommandContext

	// struct flags
	Flag NameFlag
	// contains filtered or unexported fields
}

func NewSubcommand

func NewSubcommand(cmd interface{}) (*Subcommand, error)

func (*Subcommand) InitCommands

func (sub *Subcommand) InitCommands(ctx *Context) error

InitCommands fills a Subcommand with a context. This shouldn't be called at all, rather you should use the RegisterSubcommand method of a Context.

func (*Subcommand) Name

func (sub *Subcommand) Name() string

Name returns the command name in lower case. This only returns non-zero for subcommands.

func (*Subcommand) NeedsName

func (sub *Subcommand) NeedsName()

NeedsName sets the name for this subcommand. Like InitCommands, this shouldn't be called at all, rather you should use RegisterSubcommand.

type Usager

type Usager interface {
	Usage() string
}

Usager is optionally used to override the generated usage for either an argument, or multiple (using ManualParseable).

Directories

Path Synopsis
extras

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL