Changeset 150 in code for trunk


Ignore:
Timestamp:
Mar 25, 2020, 8:03:13 PM (5 years ago)
Author:
contact
Message:

Make BouncerServ commands a tree

For instance, replace "create-network" with "network create".

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/service.go

    r120 r150  
    1313const serviceNick = "BouncerServ"
    1414
     15type serviceCommandSet map[string]*serviceCommand
     16
    1517type serviceCommand struct {
    16         usage  string
    17         desc   string
    18         handle func(dc *downstreamConn, params []string) error
     18        usage    string
     19        desc     string
     20        handle   func(dc *downstreamConn, params []string) error
     21        children serviceCommandSet
    1922}
    2023
     
    3437        }
    3538
    36         var name string
    37         var params []string
    38         if len(words) > 0 {
    39                 name = strings.ToLower(words[0])
    40                 params = words[1:]
    41         }
    42 
    43         cmd, ok := serviceCommands[name]
    44         if !ok {
    45                 sendServicePRIVMSG(dc, fmt.Sprintf(`error: unknown command %q (type "help" for a list of commands)`, name))
     39        cmd, params, err := serviceCommands.Get(words)
     40        if err != nil {
     41                sendServicePRIVMSG(dc, fmt.Sprintf(`error: %v (type "help" for a list of commands)`, err))
    4642                return
    4743        }
     
    5248}
    5349
    54 var serviceCommands map[string]serviceCommand
     50func (cmds serviceCommandSet) Get(params []string) (*serviceCommand, []string, error) {
     51        if len(params) == 0 {
     52                return nil, nil, fmt.Errorf("no command specified")
     53        }
     54
     55        name := params[0]
     56        params = params[1:]
     57
     58        cmd, ok := cmds[name]
     59        if !ok {
     60                for k := range cmds {
     61                        if !strings.HasPrefix(k, name) {
     62                                continue
     63                        }
     64                        if cmd != nil {
     65                                return nil, params, fmt.Errorf("command %q is ambiguous", name)
     66                        }
     67                        cmd = cmds[k]
     68                }
     69        }
     70        if cmd == nil {
     71                return nil, params, fmt.Errorf("command %q not found", name)
     72        }
     73
     74        if len(params) == 0 || len(cmd.children) == 0 {
     75                return cmd, params, nil
     76        }
     77        return cmd.children.Get(params)
     78}
     79
     80var serviceCommands serviceCommandSet
    5581
    5682func init() {
    57         serviceCommands = map[string]serviceCommand{
     83        serviceCommands = serviceCommandSet{
    5884                "help": {
    5985                        usage:  "[command]",
     
    6187                        handle: handleServiceHelp,
    6288                },
    63                 "create-network": {
    64                         usage:  "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick]",
    65                         desc:   "add a new network",
    66                         handle: handleServiceCreateNetwork,
     89                "network": {
     90                        children: serviceCommandSet{
     91                                "create": {
     92                                        usage:  "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick]",
     93                                        desc:   "add a new network",
     94                                        handle: handleServiceCreateNetwork,
     95                                },
     96                        },
    6797                },
     98        }
     99}
     100
     101func appendServiceCommandSetHelp(cmds serviceCommandSet, prefix []string, l *[]string) {
     102        for name, cmd := range cmds {
     103                words := append(prefix, name)
     104                if len(cmd.children) == 0 {
     105                        s := strings.Join(words, " ")
     106                        *l = append(*l, s)
     107                } else {
     108                        appendServiceCommandSetHelp(cmd.children, words, l)
     109                }
    68110        }
    69111}
     
    71113func handleServiceHelp(dc *downstreamConn, params []string) error {
    72114        if len(params) > 0 {
    73                 name := strings.ToLower(params[0])
    74                 cmd, ok := serviceCommands[name]
    75                 if !ok {
    76                         return fmt.Errorf("unknown command %q", name)
     115                cmd, rest, err := serviceCommands.Get(params)
     116                if err != nil {
     117                        return err
    77118                }
     119                words := params[:len(params)-len(rest)]
    78120
    79                 text := name
    80                 if cmd.usage != "" {
    81                         text += " " + cmd.usage
     121                if len(cmd.children) > 0 {
     122                        var l []string
     123                        appendServiceCommandSetHelp(cmd.children, words, &l)
     124                        sendServicePRIVMSG(dc, "available commands: "+strings.Join(l, ", "))
     125                } else {
     126                        text := strings.Join(words, " ")
     127                        if cmd.usage != "" {
     128                                text += " " + cmd.usage
     129                        }
     130                        text += ": " + cmd.desc
     131
     132                        sendServicePRIVMSG(dc, text)
    82133                }
    83                 text += ": " + cmd.desc
    84 
    85                 sendServicePRIVMSG(dc, text)
    86134        } else {
    87135                var l []string
    88                 for name := range serviceCommands {
    89                         l = append(l, name)
    90                 }
     136                appendServiceCommandSetHelp(serviceCommands, nil, &l)
    91137                sendServicePRIVMSG(dc, "available commands: "+strings.Join(l, ", "))
    92138        }
     
    108154        }
    109155        if *addr == "" {
    110                 return fmt.Errorf("flag addr is required")
     156                return fmt.Errorf("flag -addr is required")
    111157        }
    112158
  • trunk/soju.1.scd

    r122 r150  
    7272# IRC SERVICE
    7373
    74 soju exposes an IRC service called BouncerServ to manage the bouncer. Commands
    75 can be sent via regular private messages (_/msg BouncerServ <command> [args...]_).
     74soju exposes an IRC service called *BouncerServ* to manage the bouncer.
     75Commands can be sent via regular private messages
     76(_/msg BouncerServ <command> [args...]_). Commands may be written in full or
     77abbreviated form, for instance *network* can be abbreviated as *net* or just
     78*n*.
    7679
    7780*help* [command]
     
    7982        the command.
    8083
    81 *create-network* *-addr* <addr> [options...]
     84*network create* *-addr* <addr> [options...]
    8285        Connect to a new network at _addr_. _-addr_ is mandatory. Other options are:
    8386
Note: See TracChangeset for help on using the changeset viewer.