PageRenderTime 48ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/github.com/go-openapi/swag/util.go

https://github.com/housecream/server
Go | 318 lines | 244 code | 29 blank | 45 comment | 34 complexity | a0a15e3cb8b56ce883933472bedc9c9c MD5 | raw file
  1. // Copyright 2015 go-swagger maintainers
  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 swag
  15. import (
  16. "math"
  17. "reflect"
  18. "regexp"
  19. "sort"
  20. "strings"
  21. )
  22. // Taken from https://github.com/golang/lint/blob/1fab560e16097e5b69afb66eb93aab843ef77845/lint.go#L663-L698
  23. var commonInitialisms = map[string]bool{
  24. "API": true,
  25. "ASCII": true,
  26. "CPU": true,
  27. "CSS": true,
  28. "DNS": true,
  29. "EOF": true,
  30. "GUID": true,
  31. "HTML": true,
  32. "HTTPS": true,
  33. "HTTP": true,
  34. "ID": true,
  35. "IP": true,
  36. "JSON": true,
  37. "LHS": true,
  38. "QPS": true,
  39. "RAM": true,
  40. "RHS": true,
  41. "RPC": true,
  42. "SLA": true,
  43. "SMTP": true,
  44. "SSH": true,
  45. "TCP": true,
  46. "TLS": true,
  47. "TTL": true,
  48. "UDP": true,
  49. "UUID": true,
  50. "UID": true,
  51. "UI": true,
  52. "URI": true,
  53. "URL": true,
  54. "UTF8": true,
  55. "VM": true,
  56. "XML": true,
  57. "XSRF": true,
  58. "XSS": true,
  59. }
  60. var initialisms []string
  61. func init() {
  62. for k := range commonInitialisms {
  63. initialisms = append(initialisms, k)
  64. }
  65. sort.Sort(sort.Reverse(byLength(initialisms)))
  66. }
  67. // JoinByFormat joins a string array by a known format:
  68. // ssv: space separated value
  69. // tsv: tab separated value
  70. // pipes: pipe (|) separated value
  71. // csv: comma separated value (default)
  72. func JoinByFormat(data []string, format string) []string {
  73. if len(data) == 0 {
  74. return data
  75. }
  76. var sep string
  77. switch format {
  78. case "ssv":
  79. sep = " "
  80. case "tsv":
  81. sep = "\t"
  82. case "pipes":
  83. sep = "|"
  84. case "multi":
  85. return data
  86. default:
  87. sep = ","
  88. }
  89. return []string{strings.Join(data, sep)}
  90. }
  91. // SplitByFormat splits a string by a known format:
  92. // ssv: space separated value
  93. // tsv: tab separated value
  94. // pipes: pipe (|) separated value
  95. // csv: comma separated value (default)
  96. func SplitByFormat(data, format string) []string {
  97. if data == "" {
  98. return nil
  99. }
  100. var sep string
  101. switch format {
  102. case "ssv":
  103. sep = " "
  104. case "tsv":
  105. sep = "\t"
  106. case "pipes":
  107. sep = "|"
  108. case "multi":
  109. return nil
  110. default:
  111. sep = ","
  112. }
  113. var result []string
  114. for _, s := range strings.Split(data, sep) {
  115. if ts := strings.TrimSpace(s); ts != "" {
  116. result = append(result, ts)
  117. }
  118. }
  119. return result
  120. }
  121. type byLength []string
  122. func (s byLength) Len() int {
  123. return len(s)
  124. }
  125. func (s byLength) Swap(i, j int) {
  126. s[i], s[j] = s[j], s[i]
  127. }
  128. func (s byLength) Less(i, j int) bool {
  129. return len(s[i]) < len(s[j])
  130. }
  131. // Prepares strings by splitting by caps, spaces, dashes, and underscore
  132. func split(str string) (words []string) {
  133. repl := strings.NewReplacer(
  134. "@", "At ",
  135. "&", "And ",
  136. "|", "Pipe ",
  137. "$", "Dollar ",
  138. "!", "Bang ",
  139. "-", " ",
  140. "_", " ",
  141. )
  142. rex1 := regexp.MustCompile(`(\p{Lu})`)
  143. rex2 := regexp.MustCompile(`(\pL|\pM|\pN|\p{Pc})+`)
  144. str = trim(str)
  145. // Convert dash and underscore to spaces
  146. str = repl.Replace(str)
  147. // Split when uppercase is found (needed for Snake)
  148. str = rex1.ReplaceAllString(str, " $1")
  149. // check if consecutive single char things make up an initialism
  150. for _, k := range initialisms {
  151. str = strings.Replace(str, rex1.ReplaceAllString(k, " $1"), " "+k, -1)
  152. }
  153. // Get the final list of words
  154. words = rex2.FindAllString(str, -1)
  155. return
  156. }
  157. // Removes leading whitespaces
  158. func trim(str string) string {
  159. return strings.Trim(str, " ")
  160. }
  161. // Shortcut to strings.ToUpper()
  162. func upper(str string) string {
  163. return strings.ToUpper(trim(str))
  164. }
  165. // Shortcut to strings.ToLower()
  166. func lower(str string) string {
  167. return strings.ToLower(trim(str))
  168. }
  169. // ToFileName lowercases and underscores a go type name
  170. func ToFileName(name string) string {
  171. var out []string
  172. for _, w := range split(name) {
  173. out = append(out, lower(w))
  174. }
  175. return strings.Join(out, "_")
  176. }
  177. // ToCommandName lowercases and underscores a go type name
  178. func ToCommandName(name string) string {
  179. var out []string
  180. for _, w := range split(name) {
  181. out = append(out, lower(w))
  182. }
  183. return strings.Join(out, "-")
  184. }
  185. // ToHumanNameLower represents a code name as a human series of words
  186. func ToHumanNameLower(name string) string {
  187. var out []string
  188. for _, w := range split(name) {
  189. if !commonInitialisms[upper(w)] {
  190. out = append(out, lower(w))
  191. } else {
  192. out = append(out, w)
  193. }
  194. }
  195. return strings.Join(out, " ")
  196. }
  197. // ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
  198. func ToHumanNameTitle(name string) string {
  199. var out []string
  200. for _, w := range split(name) {
  201. uw := upper(w)
  202. if !commonInitialisms[uw] {
  203. out = append(out, upper(w[:1])+lower(w[1:]))
  204. } else {
  205. out = append(out, w)
  206. }
  207. }
  208. return strings.Join(out, " ")
  209. }
  210. // ToJSONName camelcases a name which can be underscored or pascal cased
  211. func ToJSONName(name string) string {
  212. var out []string
  213. for i, w := range split(name) {
  214. if i == 0 {
  215. out = append(out, lower(w))
  216. continue
  217. }
  218. out = append(out, upper(w[:1])+lower(w[1:]))
  219. }
  220. return strings.Join(out, "")
  221. }
  222. // ToVarName camelcases a name which can be underscored or pascal cased
  223. func ToVarName(name string) string {
  224. res := ToGoName(name)
  225. if len(res) <= 1 {
  226. return lower(res)
  227. }
  228. return lower(res[:1]) + res[1:]
  229. }
  230. // ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
  231. func ToGoName(name string) string {
  232. var out []string
  233. for _, w := range split(name) {
  234. uw := upper(w)
  235. mod := int(math.Min(float64(len(uw)), 2))
  236. if !commonInitialisms[uw] && !commonInitialisms[uw[:len(uw)-mod]] {
  237. uw = upper(w[:1]) + lower(w[1:])
  238. }
  239. out = append(out, uw)
  240. }
  241. return strings.Join(out, "")
  242. }
  243. // ContainsStringsCI searches a slice of strings for a case-insensitive match
  244. func ContainsStringsCI(coll []string, item string) bool {
  245. for _, a := range coll {
  246. if strings.EqualFold(a, item) {
  247. return true
  248. }
  249. }
  250. return false
  251. }
  252. type zeroable interface {
  253. IsZero() bool
  254. }
  255. // IsZero returns true when the value passed into the function is a zero value.
  256. // This allows for safer checking of interface values.
  257. func IsZero(data interface{}) bool {
  258. // check for things that have an IsZero method instead
  259. if vv, ok := data.(zeroable); ok {
  260. return vv.IsZero()
  261. }
  262. // continue with slightly more complex reflection
  263. v := reflect.ValueOf(data)
  264. switch v.Kind() {
  265. case reflect.String:
  266. return v.Len() == 0
  267. case reflect.Bool:
  268. return !v.Bool()
  269. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  270. return v.Int() == 0
  271. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  272. return v.Uint() == 0
  273. case reflect.Float32, reflect.Float64:
  274. return v.Float() == 0
  275. case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  276. return v.IsNil()
  277. case reflect.Struct, reflect.Array:
  278. return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface())
  279. case reflect.Invalid:
  280. return true
  281. }
  282. return false
  283. }
  284. // CommandLineOptionsGroup represents a group of user-defined command line options
  285. type CommandLineOptionsGroup struct {
  286. ShortDescription string
  287. LongDescription string
  288. Options interface{}
  289. }