mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-06-09 11:52:37 +03:00
CommandHandler func -> Command struct
This commit is contained in:
parent
6f7410c7a0
commit
fb7cd83821
@ -18,52 +18,59 @@ var ErrNoOwner = errors.New("command without owner")
|
|||||||
// of arguments.
|
// of arguments.
|
||||||
var ErrMissingArg = errors.New("missing argument")
|
var ErrMissingArg = errors.New("missing argument")
|
||||||
|
|
||||||
// CommandHandler is the function signature for command handlers..
|
// The error returned when a command is added without a prefix.
|
||||||
type CommandHandler func(*Channel, CommandMsg) error
|
var ErrMissingPrefix = errors.New("command missing prefix")
|
||||||
|
|
||||||
|
// Command is a definition of a handler for a command.
|
||||||
|
type Command struct {
|
||||||
|
Prefix string
|
||||||
|
PrefixHelp string
|
||||||
|
Help string
|
||||||
|
Handler func(*Channel, CommandMsg) error
|
||||||
|
}
|
||||||
|
|
||||||
// Commands is a registry of available commands.
|
// Commands is a registry of available commands.
|
||||||
type Commands struct {
|
type Commands struct {
|
||||||
handlers map[string]CommandHandler
|
commands map[string]Command
|
||||||
help map[string]string
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommands returns a new Commands registry.
|
// NewCommands returns a new Commands registry.
|
||||||
func NewCommands() *Commands {
|
func NewCommands() *Commands {
|
||||||
return &Commands{
|
return &Commands{
|
||||||
handlers: map[string]CommandHandler{},
|
commands: map[string]Command{},
|
||||||
help: map[string]string{},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add will register a command. If help string is empty, it will be hidden from
|
// Add will register a command. If help string is empty, it will be hidden from
|
||||||
// Help().
|
// Help().
|
||||||
func (c Commands) Add(command string, help string, handler CommandHandler) {
|
func (c *Commands) Add(cmd Command) error {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
c.handlers[command] = handler
|
if cmd.Prefix == "" {
|
||||||
|
return ErrMissingPrefix
|
||||||
if help != "" {
|
|
||||||
c.help[command] = help
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.commands[cmd.Prefix] = cmd
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alias will add another command for the same handler, won't get added to help.
|
// Alias will add another command for the same handler, won't get added to help.
|
||||||
func (c Commands) Alias(command string, alias string) error {
|
func (c *Commands) Alias(command string, alias string) error {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
handler, ok := c.handlers[command]
|
cmd, ok := c.commands[command]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrInvalidCommand
|
return ErrInvalidCommand
|
||||||
}
|
}
|
||||||
c.handlers[alias] = handler
|
c.commands[alias] = cmd
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run executes a command message.
|
// Run executes a command message.
|
||||||
func (c Commands) Run(channel *Channel, msg CommandMsg) error {
|
func (c *Commands) Run(channel *Channel, msg CommandMsg) error {
|
||||||
if msg.From == nil {
|
if msg.From == nil {
|
||||||
return ErrNoOwner
|
return ErrNoOwner
|
||||||
}
|
}
|
||||||
@ -71,22 +78,22 @@ func (c Commands) Run(channel *Channel, msg CommandMsg) error {
|
|||||||
c.RLock()
|
c.RLock()
|
||||||
defer c.RUnlock()
|
defer c.RUnlock()
|
||||||
|
|
||||||
handler, ok := c.handlers[msg.Command()]
|
cmd, ok := c.commands[msg.Command()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrInvalidCommand
|
return ErrInvalidCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler(channel, msg)
|
return cmd.Handler(channel, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Help will return collated help text as one string.
|
// Help will return collated help text as one string.
|
||||||
func (c Commands) Help() string {
|
func (c *Commands) Help() string {
|
||||||
c.RLock()
|
c.RLock()
|
||||||
defer c.RUnlock()
|
defer c.RUnlock()
|
||||||
|
|
||||||
r := []string{}
|
r := []string{}
|
||||||
for cmd, line := range c.help {
|
for _, cmd := range c.commands {
|
||||||
r = append(r, fmt.Sprintf("%s %s", cmd, line))
|
r = append(r, fmt.Sprintf("%s %s - %s", cmd.Prefix, cmd.PrefixHelp, cmd.Help))
|
||||||
}
|
}
|
||||||
sort.Strings(r)
|
sort.Strings(r)
|
||||||
|
|
||||||
@ -98,12 +105,17 @@ var defaultCmdHandlers *Commands
|
|||||||
func init() {
|
func init() {
|
||||||
c := NewCommands()
|
c := NewCommands()
|
||||||
|
|
||||||
c.Add("/help", "", func(channel *Channel, msg CommandMsg) error {
|
c.Add(Command{
|
||||||
|
Prefix: "/help",
|
||||||
|
Handler: func(channel *Channel, msg CommandMsg) error {
|
||||||
channel.Send(NewSystemMsg("Available commands:"+Newline+c.Help(), msg.From()))
|
channel.Send(NewSystemMsg("Available commands:"+Newline+c.Help(), msg.From()))
|
||||||
return nil
|
return nil
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
c.Add("/me", "", func(channel *Channel, msg CommandMsg) error {
|
c.Add(Command{
|
||||||
|
Prefix: "/me",
|
||||||
|
Handler: func(channel *Channel, msg CommandMsg) error {
|
||||||
me := strings.TrimLeft(msg.body, "/me")
|
me := strings.TrimLeft(msg.body, "/me")
|
||||||
if me == "" {
|
if me == "" {
|
||||||
me = " is at a loss for words."
|
me = " is at a loss for words."
|
||||||
@ -113,15 +125,24 @@ func init() {
|
|||||||
|
|
||||||
channel.Send(NewEmoteMsg(me, msg.From()))
|
channel.Send(NewEmoteMsg(me, msg.From()))
|
||||||
return nil
|
return nil
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
c.Add("/exit", "- Exit the chat.", func(channel *Channel, msg CommandMsg) error {
|
c.Add(Command{
|
||||||
|
Prefix: "/exit",
|
||||||
|
Help: "Exit the chat.",
|
||||||
|
Handler: func(channel *Channel, msg CommandMsg) error {
|
||||||
msg.From().Close()
|
msg.From().Close()
|
||||||
return nil
|
return nil
|
||||||
|
},
|
||||||
})
|
})
|
||||||
c.Alias("/exit", "/quit")
|
c.Alias("/exit", "/quit")
|
||||||
|
|
||||||
c.Add("/nick", "NAME - Rename yourself.", func(channel *Channel, msg CommandMsg) error {
|
c.Add(Command{
|
||||||
|
Prefix: "/nick",
|
||||||
|
PrefixHelp: "NAME",
|
||||||
|
Help: "Rename yourself.",
|
||||||
|
Handler: func(channel *Channel, msg CommandMsg) error {
|
||||||
args := msg.Args()
|
args := msg.Args()
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return ErrMissingArg
|
return ErrMissingArg
|
||||||
@ -133,18 +154,27 @@ func init() {
|
|||||||
body := fmt.Sprintf("%s is now known as %s.", oldName, u.Name())
|
body := fmt.Sprintf("%s is now known as %s.", oldName, u.Name())
|
||||||
channel.Send(NewAnnounceMsg(body))
|
channel.Send(NewAnnounceMsg(body))
|
||||||
return nil
|
return nil
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
c.Add("/names", "- List users who are connected.", func(channel *Channel, msg CommandMsg) error {
|
c.Add(Command{
|
||||||
|
Prefix: "/names",
|
||||||
|
Help: "List users who are connected.",
|
||||||
|
Handler: func(channel *Channel, msg CommandMsg) error {
|
||||||
// TODO: colorize
|
// TODO: colorize
|
||||||
names := channel.NamesPrefix("")
|
names := channel.NamesPrefix("")
|
||||||
body := fmt.Sprintf("%d connected: %s", len(names), strings.Join(names, ", "))
|
body := fmt.Sprintf("%d connected: %s", len(names), strings.Join(names, ", "))
|
||||||
channel.Send(NewSystemMsg(body, msg.From()))
|
channel.Send(NewSystemMsg(body, msg.From()))
|
||||||
return nil
|
return nil
|
||||||
|
},
|
||||||
})
|
})
|
||||||
c.Alias("/names", "/list")
|
c.Alias("/names", "/list")
|
||||||
|
|
||||||
c.Add("/theme", "[mono|colors] - Set your color theme.", func(channel *Channel, msg CommandMsg) error {
|
c.Add(Command{
|
||||||
|
Prefix: "/theme",
|
||||||
|
PrefixHelp: "[mono|colors]",
|
||||||
|
Help: "Set your color theme.",
|
||||||
|
Handler: func(channel *Channel, msg CommandMsg) error {
|
||||||
user := msg.From()
|
user := msg.From()
|
||||||
args := msg.Args()
|
args := msg.Args()
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
@ -167,6 +197,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errors.New("theme not found")
|
return errors.New("theme not found")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
defaultCmdHandlers = c
|
defaultCmdHandlers = c
|
||||||
|
Loading…
x
Reference in New Issue
Block a user