utils.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package utils
  15. import (
  16. "bytes"
  17. "fmt"
  18. "net/url"
  19. "reflect"
  20. "strings"
  21. "unicode"
  22. )
  23. func isUpperChar(ch byte) bool {
  24. return ch >= 'A' && ch <= 'Z'
  25. }
  26. func isLowerChar(ch byte) bool {
  27. return (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
  28. }
  29. func CamelSplit(str string, sep string) string {
  30. tokens := CamelSplitTokens(str)
  31. return strings.Join(tokens, sep)
  32. }
  33. func CamelSplitTokens(str string) []string {
  34. var (
  35. tokens = make([]string, 0, 4)
  36. buf = make([]byte, 0, 16)
  37. upperCount int
  38. )
  39. for i := range str {
  40. var (
  41. c = str[i]
  42. inc = true
  43. split bool
  44. )
  45. if isUpperChar(c) {
  46. upperCount += 1
  47. if upperCount == 1 {
  48. split = true
  49. } else if upperCount > 2 && i+1 < len(str) && isLowerChar(str[i+1]) {
  50. split = true
  51. }
  52. c += 'a' - 'A'
  53. } else if isLowerChar(c) {
  54. upperCount = 0
  55. } else {
  56. upperCount = 0
  57. split = true
  58. // For non-alphanumeric characters at the end of the string,
  59. // include them in the current buffer before splitting to preserve them
  60. if i == len(str)-1 && len(buf) > 0 {
  61. buf = append(buf, c)
  62. }
  63. inc = false
  64. }
  65. if split && len(buf) > 0 {
  66. tokens = append(tokens, string(buf))
  67. buf = buf[:0]
  68. }
  69. if inc {
  70. buf = append(buf, c)
  71. }
  72. }
  73. if len(buf) > 0 {
  74. tokens = append(tokens, string(buf))
  75. }
  76. return tokens
  77. }
  78. func Capitalize(str string) string {
  79. if len(str) >= 1 {
  80. return strings.ToUpper(str[:1]) + strings.ToLower(str[1:])
  81. } else {
  82. return str
  83. }
  84. }
  85. func Kebab2Camel(kebab string, sep string) string {
  86. var buf bytes.Buffer
  87. segs := strings.Split(kebab, sep)
  88. for _, s := range segs {
  89. buf.WriteString(Capitalize(s))
  90. }
  91. return buf.String()
  92. }
  93. var TRUE_STRS = []string{"1", "true", "on", "yes"}
  94. func ToBool(str string) bool {
  95. val := strings.ToLower(strings.TrimSpace(str))
  96. for _, v := range TRUE_STRS {
  97. if v == val {
  98. return true
  99. }
  100. }
  101. return false
  102. }
  103. func DecodeMeta(str string) string {
  104. s, e := url.QueryUnescape(str)
  105. if e == nil && s != str {
  106. return DecodeMeta(s)
  107. } else {
  108. return str
  109. }
  110. }
  111. func IsInStringArray(val string, array []string) bool {
  112. return IsInArray(val, array)
  113. }
  114. func InStringArray(val string, array []string) (ok bool, i int) {
  115. return InArray2(val, array)
  116. }
  117. func InArray2[T int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64 | float32 | float64 | string](val T, array []T) (ok bool, i int) {
  118. for i = range array {
  119. if ok = array[i] == val; ok {
  120. return
  121. }
  122. }
  123. return
  124. }
  125. func IsInArray[T int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64 | float32 | float64 | string](val T, array []T) bool {
  126. for _, ele := range array {
  127. if ele == val {
  128. return true
  129. }
  130. }
  131. return false
  132. }
  133. func InArray(v interface{}, in interface{}) (ok bool, i int) {
  134. val := reflect.Indirect(reflect.ValueOf(in))
  135. switch val.Kind() {
  136. case reflect.Slice, reflect.Array:
  137. for ; i < val.Len(); i++ {
  138. if ok = v == val.Index(i).Interface(); ok {
  139. return
  140. }
  141. }
  142. }
  143. return
  144. }
  145. func TruncateString(v interface{}, maxLen int) string {
  146. str := fmt.Sprintf("%s", v)
  147. if len(str) > maxLen {
  148. str = str[:maxLen] + ".."
  149. }
  150. return str
  151. }
  152. func IsAscii(str string) bool {
  153. for _, c := range str {
  154. if c > unicode.MaxASCII {
  155. return false
  156. }
  157. }
  158. return true
  159. }
  160. func FloatRound(num float64, precision int) float64 {
  161. for i := 0; i < precision; i++ {
  162. num *= 10
  163. }
  164. temp := float64(int64(num))
  165. for i := 0; i < precision; i++ {
  166. temp /= 10.0
  167. }
  168. num = temp
  169. return num
  170. }
  171. func getStringInQuote(s string, start, length int, quote byte, backIndex int) (string, int) {
  172. var i = start + 1
  173. if quote != '\'' && quote != '"' {
  174. for i < length {
  175. if s[i] == ' ' || s[i] == '\'' || s[i] == '"' {
  176. return s[backIndex:i], i
  177. }
  178. i++
  179. }
  180. return s[backIndex:], i
  181. } else {
  182. for i < length {
  183. if s[i] == quote {
  184. return s[backIndex+1 : i], i + 1
  185. }
  186. i++
  187. }
  188. return s[backIndex:], i
  189. }
  190. }
  191. func ArgsStringToArray(s string) []string {
  192. var args, i, j = make([]string, 0), 0, 0
  193. var length = len(s)
  194. for i < length {
  195. switch s[i] {
  196. case ' ':
  197. if i > j {
  198. args = append(args, s[j:i])
  199. j = i
  200. }
  201. i++
  202. j = i
  203. case '"':
  204. var s1, s2 string
  205. var oldStr = s[j:i]
  206. s1, i = getStringInQuote(s, i, length, '"', i)
  207. s1 = oldStr + s1
  208. for i < length && s[i] != ' ' {
  209. s2, i = getStringInQuote(s, i, length, s[i], i)
  210. s1 += s2
  211. fmt.Println(s2)
  212. }
  213. args = append(args, s1)
  214. i++
  215. j = i
  216. case '\'':
  217. var s1, s2 string
  218. var oldStr = s[j:i]
  219. s1, i = getStringInQuote(s, i, length, '\'', i)
  220. s1 = oldStr + s1
  221. for i < length && s[i] != ' ' {
  222. s2, i = getStringInQuote(s, i, length, s[i], i)
  223. s1 += s2
  224. }
  225. args = append(args, s1)
  226. i++
  227. j = i
  228. default:
  229. i++
  230. }
  231. }
  232. if j < length {
  233. args = append(args, s[j:])
  234. }
  235. return args
  236. }