sayori

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2020 License: BSD-3-Clause Imports: 3 Imported by: 0

README

sayori

sayori is a dead simple command router based on discordgo.

sayori uses no reflection and has no concept of subcommands, forming a 'flat' hierarchy.

Command and Event are interfaces that describe entities that only run on a MessageCreate Discord event. A Command composes of an Event with prefix and alias matching, and argument parsing. Parsing arguments in an Event is also optional.

You can bind a Command or Event to the router by plugging it into .Command or .Event and wrapping that with .Has, as shown in the example. Filters can then be chained onto these handlers to control when the bound command handler fires. A given Filter will inspect the MessageCreate invocation context and if a match is found, will prevent the command handler from firing.

Alternatively, .HandleDefault is available if you want to implement your own handler that does not satisfy Command or Event.

More details on these interfaces are defined in /router.go.

To initialize sayori, a Prefixer must be defined. A Prefixer can load a prefix based on guildID or use a default prefix. This will only be used for parsing a Command.

dg, err := discordgo.New("Bot " + Token)
if err != nil {
	fmt.Println("error creating Discord session,", err)
	return
}

router := sayori.New(dg, &Prefixer{})
router.Has(router.Command(&EchoCmd{}))

router.Has(router.Event(&OnMsg{}).
	Filter(sayori.MessagesBot).
	Filter(sayori.MessagesEmpty).
	Filter(sayori.MessagesSelf))

router.HasOnce(router.HandleDefault(func(_ *discordgo.Session, d *discordgo.MessageDelete) {
	log.Printf("A message was deleted: %v, %v, %v", d.Message.ID, d.Message.ChannelID, d.Message.GuildID)
}, nil))

getting started

installation

go get github.com/pixeltopic/sayori

See /examples for detailed usage.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Args

type Args map[string]interface{}

Args is a set of args bound to identifiers that are parsed from the command

func NewArgs

func NewArgs() Args

NewArgs makes a new instance of Args for storing key-argument mappings

func (Args) Delete

func (a Args) Delete(key string)

Delete removes a key that maps to val in args, or if key does not exist, no-op

func (Args) Load

func (a Args) Load(key string) (interface{}, bool)

Load loads a key from args

func (Args) Store

func (a Args) Store(key string, val interface{})

Store stores a key that maps to val in args

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder generates the framework of a command.

func (*Builder) Filter

func (b *Builder) Filter(f Filter) *Builder

Filter prevents the specified condition from firing the Command or Event

type Command

type Command interface {
	Event
	Parseable
	Match(toks Toks) (string, bool)
}

Command is used to handle a command which will only be run on a `*discordgo.MessageCreate` event. Encapsulates the implementation of both `Event` and `Parseable`.

`Match` is where a command with a trimmed prefix will be matched an alias. It returns an alias parsed from the command with an `ok` bool. If `ok` is false, the Command will immediately be terminated.

type Context

type Context struct {
	Filter
	Session      *discordgo.Session
	Message      *discordgo.Message
	Prefix       string
	Alias        string
	Args         Args
	Toks         Toks
	Err          error
	FmtFilterErr func(Filter) string // format a Filter into an error string
}

Context contains data relating to the command invocation context

func NewContext

func NewContext() Context

NewContext returns an unpopulated context with defaults set

type Event

type Event interface {
	Handle(ctx Context) error
	Resolve(ctx Context)
}

Event is used to handle a `*discordgo.MessageCreate` event. Only contains the core functions required to implement a `Command`, thus does not require a prefix or alias to be parsed. Can optionally implement `Parseable`, but is not required.

`Handle` is where a command's business logic should belong.

`Resolve` is where an error in `ctx.Err` can be handled, along with any other necessary cleanup. It will always be the last function run.

type Filter

type Filter int

Filter represents a condition that prevents a `Command` or `Event` from firing. Only use the given const filters which range from 2^0 to 2^4.

const (
	MessagesSelf Filter = 1 << iota
	MessagesBot
	MessagesEmpty
	MessagesPrivate
	MessagesGuild
)

Valid Filters

func NewFilter

func NewFilter(filters ...Filter) Filter

NewFilter generates a Filter bitset given filters and performing a bitwise `or` on all of them

func (Filter) Contains

func (f Filter) Contains(filter Filter) bool

Contains returns true if the given filter is part of the current filter

type FilterError

type FilterError struct {
	// contains filtered or unexported fields
}

FilterError is an error that has a failing Filter attached

func (*FilterError) Error

func (e *FilterError) Error() string

func (*FilterError) Filter

func (e *FilterError) Filter() Filter

Filter returns the violated filter

type Parseable

type Parseable interface {
	Parse(toks Toks) (Args, error)
}

Parseable represents an entity that can be parsed. It is implemented by `Command` but optional for `Event`

`Parse` is where `Toks` will be parsed into `Args`. If an error is non-nil, will immediately be handled by `Resolve(ctx Context)`

type Prefixer

type Prefixer interface {
	Load(guildID string) (string, bool)
	Default() string
}

Prefixer identifies the prefix based on the guildID before a `Command` execution and removes the prefix of the command string if matched.

`Load` fetches a prefix that matches the `guildID` and returns the prefix mapped to the `guildID` with an `ok` bool.

`Default` returns the default prefix

type Router

type Router struct {
	*discordgo.Session
	// contains filtered or unexported fields
}

Router maps commands to handlers.

func New

func New(s *discordgo.Session, p Prefixer) *Router

New returns a new Router.

func (*Router) Command

func (r *Router) Command(c Command) *Builder

Command binds a `Command` implementation to the builder.

func (*Router) Event

func (r *Router) Event(e Event) *Builder

Event binds an `Event` implementation to the builder.

func (*Router) HandleDefault

func (r *Router) HandleDefault(h interface{}) *Builder

HandleDefault binds a default discordgo event handler to the builder.

func (*Router) Has

func (r *Router) Has(b *Builder)

Has binds a `Builder` to the router which should implement `Event` or `Command` with any desired `Filter` to control when the handler fires.

`Filter` has consts defined in the package that start with the prefix `Messages*`

func (*Router) HasOnce

func (r *Router) HasOnce(b *Builder)

HasOnce binds a `Builder` to the router which should implement `Event` or `Command` with any desired `Filter` to control when the handler fires.

`Filter` has consts defined in the package that start with the prefix `Messages*`

`b` will only fire at most once.

type Toks

type Toks struct {
	// contains filtered or unexported fields
}

Toks are the tokens parsed from the command

func NewToks

func NewToks(s string) Toks

NewToks returns a slice of tokens split by whitespace

func (Toks) Get

func (t Toks) Get(i int) (string, bool)

Get retrieves the token matching the index

func (Toks) Iter

func (t Toks) Iter() []string

Iter returns an iterable Toks.

func (Toks) Len

func (t Toks) Len() int

Len returns the amount of tokens found in the command

func (Toks) Raw

func (t Toks) Raw() string

Raw returns the raw, untokenized string

func (Toks) Set

func (t Toks) Set(i int, tok string) bool

Set updates an existing token with a new value for all values of the Tok instance and returns an ok state.

This is not concurrency-safe.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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