mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 23:32:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			202 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2015 go-swagger maintainers
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //    http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| package swag
 | |
| 
 | |
| import (
 | |
| 	"sort"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// commonInitialisms are common acronyms that are kept as whole uppercased words.
 | |
| 	commonInitialisms *indexOfInitialisms
 | |
| 
 | |
| 	// initialisms is a slice of sorted initialisms
 | |
| 	initialisms []string
 | |
| 
 | |
| 	// a copy of initialisms pre-baked as []rune
 | |
| 	initialismsRunes      [][]rune
 | |
| 	initialismsUpperCased [][]rune
 | |
| 
 | |
| 	isInitialism func(string) bool
 | |
| 
 | |
| 	maxAllocMatches int
 | |
| )
 | |
| 
 | |
| func init() {
 | |
| 	// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
 | |
| 	configuredInitialisms := map[string]bool{
 | |
| 		"ACL":   true,
 | |
| 		"API":   true,
 | |
| 		"ASCII": true,
 | |
| 		"CPU":   true,
 | |
| 		"CSS":   true,
 | |
| 		"DNS":   true,
 | |
| 		"EOF":   true,
 | |
| 		"GUID":  true,
 | |
| 		"HTML":  true,
 | |
| 		"HTTPS": true,
 | |
| 		"HTTP":  true,
 | |
| 		"ID":    true,
 | |
| 		"IP":    true,
 | |
| 		"IPv4":  true,
 | |
| 		"IPv6":  true,
 | |
| 		"JSON":  true,
 | |
| 		"LHS":   true,
 | |
| 		"OAI":   true,
 | |
| 		"QPS":   true,
 | |
| 		"RAM":   true,
 | |
| 		"RHS":   true,
 | |
| 		"RPC":   true,
 | |
| 		"SLA":   true,
 | |
| 		"SMTP":  true,
 | |
| 		"SQL":   true,
 | |
| 		"SSH":   true,
 | |
| 		"TCP":   true,
 | |
| 		"TLS":   true,
 | |
| 		"TTL":   true,
 | |
| 		"UDP":   true,
 | |
| 		"UI":    true,
 | |
| 		"UID":   true,
 | |
| 		"UUID":  true,
 | |
| 		"URI":   true,
 | |
| 		"URL":   true,
 | |
| 		"UTF8":  true,
 | |
| 		"VM":    true,
 | |
| 		"XML":   true,
 | |
| 		"XMPP":  true,
 | |
| 		"XSRF":  true,
 | |
| 		"XSS":   true,
 | |
| 	}
 | |
| 
 | |
| 	// a thread-safe index of initialisms
 | |
| 	commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
 | |
| 	initialisms = commonInitialisms.sorted()
 | |
| 	initialismsRunes = asRunes(initialisms)
 | |
| 	initialismsUpperCased = asUpperCased(initialisms)
 | |
| 	maxAllocMatches = maxAllocHeuristic(initialismsRunes)
 | |
| 
 | |
| 	// a test function
 | |
| 	isInitialism = commonInitialisms.isInitialism
 | |
| }
 | |
| 
 | |
| func asRunes(in []string) [][]rune {
 | |
| 	out := make([][]rune, len(in))
 | |
| 	for i, initialism := range in {
 | |
| 		out[i] = []rune(initialism)
 | |
| 	}
 | |
| 
 | |
| 	return out
 | |
| }
 | |
| 
 | |
| func asUpperCased(in []string) [][]rune {
 | |
| 	out := make([][]rune, len(in))
 | |
| 
 | |
| 	for i, initialism := range in {
 | |
| 		out[i] = []rune(upper(trim(initialism)))
 | |
| 	}
 | |
| 
 | |
| 	return out
 | |
| }
 | |
| 
 | |
| func maxAllocHeuristic(in [][]rune) int {
 | |
| 	heuristic := make(map[rune]int)
 | |
| 	for _, initialism := range in {
 | |
| 		heuristic[initialism[0]]++
 | |
| 	}
 | |
| 
 | |
| 	var maxAlloc int
 | |
| 	for _, val := range heuristic {
 | |
| 		if val > maxAlloc {
 | |
| 			maxAlloc = val
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return maxAlloc
 | |
| }
 | |
| 
 | |
| // AddInitialisms add additional initialisms
 | |
| func AddInitialisms(words ...string) {
 | |
| 	for _, word := range words {
 | |
| 		// commonInitialisms[upper(word)] = true
 | |
| 		commonInitialisms.add(upper(word))
 | |
| 	}
 | |
| 	// sort again
 | |
| 	initialisms = commonInitialisms.sorted()
 | |
| 	initialismsRunes = asRunes(initialisms)
 | |
| 	initialismsUpperCased = asUpperCased(initialisms)
 | |
| }
 | |
| 
 | |
| // indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
 | |
| // Since go1.9, this may be implemented with sync.Map.
 | |
| type indexOfInitialisms struct {
 | |
| 	sortMutex *sync.Mutex
 | |
| 	index     *sync.Map
 | |
| }
 | |
| 
 | |
| func newIndexOfInitialisms() *indexOfInitialisms {
 | |
| 	return &indexOfInitialisms{
 | |
| 		sortMutex: new(sync.Mutex),
 | |
| 		index:     new(sync.Map),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
 | |
| 	m.sortMutex.Lock()
 | |
| 	defer m.sortMutex.Unlock()
 | |
| 	for k, v := range initial {
 | |
| 		m.index.Store(k, v)
 | |
| 	}
 | |
| 	return m
 | |
| }
 | |
| 
 | |
| func (m *indexOfInitialisms) isInitialism(key string) bool {
 | |
| 	_, ok := m.index.Load(key)
 | |
| 	return ok
 | |
| }
 | |
| 
 | |
| func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
 | |
| 	m.index.Store(key, true)
 | |
| 	return m
 | |
| }
 | |
| 
 | |
| func (m *indexOfInitialisms) sorted() (result []string) {
 | |
| 	m.sortMutex.Lock()
 | |
| 	defer m.sortMutex.Unlock()
 | |
| 	m.index.Range(func(key, _ interface{}) bool {
 | |
| 		k := key.(string)
 | |
| 		result = append(result, k)
 | |
| 		return true
 | |
| 	})
 | |
| 	sort.Sort(sort.Reverse(byInitialism(result)))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| type byInitialism []string
 | |
| 
 | |
| func (s byInitialism) Len() int {
 | |
| 	return len(s)
 | |
| }
 | |
| func (s byInitialism) Swap(i, j int) {
 | |
| 	s[i], s[j] = s[j], s[i]
 | |
| }
 | |
| func (s byInitialism) Less(i, j int) bool {
 | |
| 	if len(s[i]) != len(s[j]) {
 | |
| 		return len(s[i]) < len(s[j])
 | |
| 	}
 | |
| 
 | |
| 	return strings.Compare(s[i], s[j]) > 0
 | |
| }
 |