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

  1. package main
  2. import (
  3. "log"
  4. "strconv"
  5. "strings"
  6. )
  7. type Param struct {
  8. Index int
  9. Key string
  10. Value string
  11. }
  12. func (p *Param) String() *string {
  13. if p == nil {
  14. return nil
  15. }
  16. return &p.Value
  17. }
  18. func (p *Param) StringOr(fallback string) string {
  19. if p == nil {
  20. return fallback
  21. }
  22. return p.Value
  23. }
  24. func (p *Param) Int() *int {
  25. if p == nil {
  26. return nil
  27. }
  28. n, err := strconv.Atoi(p.Value)
  29. if err != nil {
  30. return nil
  31. }
  32. return &n
  33. }
  34. func (p *Param) Float() *float64 {
  35. if p == nil {
  36. return nil
  37. }
  38. n, err := strconv.ParseFloat(p.Value, 64)
  39. if err != nil {
  40. return nil
  41. }
  42. return &n
  43. }
  44. func (p *Param) Bool() *bool {
  45. if p == nil {
  46. return nil
  47. }
  48. v := strings.ToLower(p.Value)
  49. if v == "yes" || v == "true" || v == "on" {
  50. r := true
  51. return &r
  52. } else if v == "no" || v == "false" || v == "off" {
  53. r := false
  54. return &r
  55. }
  56. return nil
  57. }
  58. type Params []Param
  59. func (p Params) Get(key interface{}) *Param {
  60. switch key := key.(type) {
  61. case string:
  62. for _, p := range p {
  63. if p.Key == key {
  64. return &p
  65. }
  66. }
  67. case int:
  68. for _, p := range p {
  69. if p.Index == key {
  70. return &p
  71. }
  72. }
  73. default:
  74. log.Panicf("Incorrect key type %T", key)
  75. }
  76. return nil
  77. }
  78. func (p Params) Subset(prefix string) Params {
  79. if len(p) == 0 {
  80. return Params{}
  81. }
  82. if len(prefix) > 0 && !strings.HasSuffix(prefix, ".") {
  83. prefix += "."
  84. }
  85. res := make(Params, 0, len(p))
  86. for _, param := range p {
  87. if param.Index == -1 && strings.HasPrefix(param.Key, prefix) {
  88. res = append(res, Param{Index: -1, Key: param.Key[len(prefix):], Value: param.Value})
  89. }
  90. }
  91. return res
  92. }
  93. func (p Params) StringMap() map[string]string {
  94. res := make(map[string]string)
  95. for _, param := range p {
  96. if param.Index == -1 {
  97. res[param.Key] = param.Value
  98. }
  99. }
  100. return res
  101. }
  102. func (p Params) StringPtrMap() map[string]*string {
  103. res := make(map[string]*string)
  104. for _, param := range p {
  105. if param.Index == -1 {
  106. if param.Value == "NULL" {
  107. res[param.Key] = nil
  108. } else {
  109. res[param.Key] = &param.Value
  110. }
  111. }
  112. }
  113. return res
  114. }
  115. func (p Params) Strings(minIndex int) []string {
  116. res := make([]string, 0, len(p))
  117. for _, param := range p {
  118. if param.Index >= minIndex {
  119. res = append(res, param.Value)
  120. }
  121. }
  122. return res
  123. }
  124. type Command struct {
  125. Name string
  126. Params Params
  127. }
  128. func parseCommand(args []string) Command {
  129. if len(args) == 0 {
  130. return Command{Name: "help"}
  131. }
  132. cmd := Command{
  133. Name: args[0],
  134. Params: make(Params, 0, len(args)-1),
  135. }
  136. nextIndex := 0
  137. for _, arg := range args[1:] {
  138. kv := strings.SplitN(arg, "=", 2)
  139. if len(kv) == 2 {
  140. cmd.Params = append(cmd.Params, Param{Index: -1, Key: kv[0], Value: kv[1]})
  141. } else {
  142. cmd.Params = append(cmd.Params, Param{Index: nextIndex, Value: arg})
  143. nextIndex += 1
  144. }
  145. }
  146. return cmd
  147. }