You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
2.7 KiB
183 lines
2.7 KiB
package main
|
|
|
|
import (
|
|
"log"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type Param struct {
|
|
Index int
|
|
Key string
|
|
Value string
|
|
}
|
|
|
|
func (p *Param) String() *string {
|
|
if p == nil {
|
|
return nil
|
|
}
|
|
|
|
return &p.Value
|
|
}
|
|
|
|
func (p *Param) StringOr(fallback string) string {
|
|
if p == nil {
|
|
return fallback
|
|
}
|
|
|
|
return p.Value
|
|
}
|
|
|
|
|
|
func (p *Param) Int() *int {
|
|
if p == nil {
|
|
return nil
|
|
}
|
|
|
|
n, err := strconv.Atoi(p.Value)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
return &n
|
|
}
|
|
|
|
func (p *Param) Float() *float64 {
|
|
if p == nil {
|
|
return nil
|
|
}
|
|
|
|
n, err := strconv.ParseFloat(p.Value, 64)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
return &n
|
|
}
|
|
|
|
func (p *Param) Bool() *bool {
|
|
if p == nil {
|
|
return nil
|
|
}
|
|
|
|
v := strings.ToLower(p.Value)
|
|
if v == "yes" || v == "true" || v == "on" {
|
|
r := true
|
|
return &r
|
|
} else if v == "no" || v == "false" || v == "off" {
|
|
r := false
|
|
return &r
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type Params []Param
|
|
|
|
func (p Params) Get(key interface{}) *Param {
|
|
switch key := key.(type) {
|
|
case string:
|
|
for _, p := range p {
|
|
if p.Key == key {
|
|
return &p
|
|
}
|
|
}
|
|
case int:
|
|
for _, p := range p {
|
|
if p.Index == key {
|
|
return &p
|
|
}
|
|
}
|
|
default:
|
|
log.Panicf("Incorrect key type %T", key)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p Params) Subset(prefix string) Params {
|
|
if len(p) == 0 {
|
|
return Params{}
|
|
}
|
|
|
|
if len(prefix) > 0 && !strings.HasSuffix(prefix, ".") {
|
|
prefix += "."
|
|
}
|
|
|
|
res := make(Params, 0, len(p))
|
|
|
|
for _, param := range p {
|
|
if param.Index == -1 && strings.HasPrefix(param.Key, prefix) {
|
|
res = append(res, Param{Index: -1, Key: param.Key[len(prefix):], Value: param.Value})
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func (p Params) StringMap() map[string]string {
|
|
res := make(map[string]string)
|
|
for _, param := range p {
|
|
if param.Index == -1 {
|
|
res[param.Key] = param.Value
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func (p Params) StringPtrMap() map[string]*string {
|
|
res := make(map[string]*string)
|
|
for _, param := range p {
|
|
if param.Index == -1 {
|
|
if param.Value == "NULL" {
|
|
res[param.Key] = nil
|
|
} else {
|
|
res[param.Key] = ¶m.Value
|
|
}
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func (p Params) Strings(minIndex int) []string {
|
|
res := make([]string, 0, len(p))
|
|
for _, param := range p {
|
|
if param.Index >= minIndex {
|
|
res = append(res, param.Value)
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
type Command struct {
|
|
Name string
|
|
Params Params
|
|
}
|
|
|
|
func parseCommand(args []string) Command {
|
|
if len(args) == 0 {
|
|
return Command{Name: "help"}
|
|
}
|
|
|
|
cmd := Command{
|
|
Name: args[0],
|
|
Params: make(Params, 0, len(args)-1),
|
|
}
|
|
|
|
nextIndex := 0
|
|
for _, arg := range args[1:] {
|
|
kv := strings.SplitN(arg, "=", 2)
|
|
|
|
if len(kv) == 2 {
|
|
cmd.Params = append(cmd.Params, Param{Index: -1, Key: kv[0], Value: kv[1]})
|
|
} else {
|
|
cmd.Params = append(cmd.Params, Param{Index: nextIndex, Value: arg})
|
|
nextIndex += 1
|
|
}
|
|
}
|
|
|
|
return cmd
|
|
}
|