1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package swag
16
17 import (
18 "sort"
19 "strings"
20 "sync"
21 )
22
23 var (
24
25 commonInitialisms *indexOfInitialisms
26
27
28 initialisms []string
29
30
31 initialismsRunes [][]rune
32 initialismsUpperCased [][]rune
33
34 isInitialism func(string) bool
35
36 maxAllocMatches int
37 )
38
39 func init() {
40
41 configuredInitialisms := map[string]bool{
42 "ACL": true,
43 "API": true,
44 "ASCII": true,
45 "CPU": true,
46 "CSS": true,
47 "DNS": true,
48 "EOF": true,
49 "GUID": true,
50 "HTML": true,
51 "HTTPS": true,
52 "HTTP": true,
53 "ID": true,
54 "IP": true,
55 "IPv4": true,
56 "IPv6": true,
57 "JSON": true,
58 "LHS": true,
59 "OAI": true,
60 "QPS": true,
61 "RAM": true,
62 "RHS": true,
63 "RPC": true,
64 "SLA": true,
65 "SMTP": true,
66 "SQL": true,
67 "SSH": true,
68 "TCP": true,
69 "TLS": true,
70 "TTL": true,
71 "UDP": true,
72 "UI": true,
73 "UID": true,
74 "UUID": true,
75 "URI": true,
76 "URL": true,
77 "UTF8": true,
78 "VM": true,
79 "XML": true,
80 "XMPP": true,
81 "XSRF": true,
82 "XSS": true,
83 }
84
85
86 commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
87 initialisms = commonInitialisms.sorted()
88 initialismsRunes = asRunes(initialisms)
89 initialismsUpperCased = asUpperCased(initialisms)
90 maxAllocMatches = maxAllocHeuristic(initialismsRunes)
91
92
93 isInitialism = commonInitialisms.isInitialism
94 }
95
96 func asRunes(in []string) [][]rune {
97 out := make([][]rune, len(in))
98 for i, initialism := range in {
99 out[i] = []rune(initialism)
100 }
101
102 return out
103 }
104
105 func asUpperCased(in []string) [][]rune {
106 out := make([][]rune, len(in))
107
108 for i, initialism := range in {
109 out[i] = []rune(upper(trim(initialism)))
110 }
111
112 return out
113 }
114
115 func maxAllocHeuristic(in [][]rune) int {
116 heuristic := make(map[rune]int)
117 for _, initialism := range in {
118 heuristic[initialism[0]]++
119 }
120
121 var maxAlloc int
122 for _, val := range heuristic {
123 if val > maxAlloc {
124 maxAlloc = val
125 }
126 }
127
128 return maxAlloc
129 }
130
131
132 func AddInitialisms(words ...string) {
133 for _, word := range words {
134
135 commonInitialisms.add(upper(word))
136 }
137
138 initialisms = commonInitialisms.sorted()
139 initialismsRunes = asRunes(initialisms)
140 initialismsUpperCased = asUpperCased(initialisms)
141 }
142
143
144
145 type indexOfInitialisms struct {
146 sortMutex *sync.Mutex
147 index *sync.Map
148 }
149
150 func newIndexOfInitialisms() *indexOfInitialisms {
151 return &indexOfInitialisms{
152 sortMutex: new(sync.Mutex),
153 index: new(sync.Map),
154 }
155 }
156
157 func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
158 m.sortMutex.Lock()
159 defer m.sortMutex.Unlock()
160 for k, v := range initial {
161 m.index.Store(k, v)
162 }
163 return m
164 }
165
166 func (m *indexOfInitialisms) isInitialism(key string) bool {
167 _, ok := m.index.Load(key)
168 return ok
169 }
170
171 func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
172 m.index.Store(key, true)
173 return m
174 }
175
176 func (m *indexOfInitialisms) sorted() (result []string) {
177 m.sortMutex.Lock()
178 defer m.sortMutex.Unlock()
179 m.index.Range(func(key, _ interface{}) bool {
180 k := key.(string)
181 result = append(result, k)
182 return true
183 })
184 sort.Sort(sort.Reverse(byInitialism(result)))
185 return
186 }
187
188 type byInitialism []string
189
190 func (s byInitialism) Len() int {
191 return len(s)
192 }
193 func (s byInitialism) Swap(i, j int) {
194 s[i], s[j] = s[j], s[i]
195 }
196 func (s byInitialism) Less(i, j int) bool {
197 if len(s[i]) != len(s[j]) {
198 return len(s[i]) < len(s[j])
199 }
200
201 return strings.Compare(s[i], s[j]) > 0
202 }
203
View as plain text