mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	re-vendor k8s.io/kube-openapi
This commit is contained in:
		
							
								
								
									
										1
									
								
								vendor/github.com/go-openapi/swag/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-openapi/swag/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,3 +2,4 @@ secrets.yml
 | 
			
		||||
vendor
 | 
			
		||||
Godeps
 | 
			
		||||
.idea
 | 
			
		||||
*.out
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								vendor/github.com/go-openapi/swag/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/go-openapi/swag/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,14 +4,14 @@ linters-settings:
 | 
			
		||||
  golint:
 | 
			
		||||
    min-confidence: 0
 | 
			
		||||
  gocyclo:
 | 
			
		||||
    min-complexity: 25
 | 
			
		||||
    min-complexity: 45
 | 
			
		||||
  maligned:
 | 
			
		||||
    suggest-new: true
 | 
			
		||||
  dupl:
 | 
			
		||||
    threshold: 100
 | 
			
		||||
    threshold: 200
 | 
			
		||||
  goconst:
 | 
			
		||||
    min-len: 3
 | 
			
		||||
    min-occurrences: 2
 | 
			
		||||
    min-occurrences: 3
 | 
			
		||||
 | 
			
		||||
linters:
 | 
			
		||||
  enable-all: true
 | 
			
		||||
@@ -20,35 +20,41 @@ linters:
 | 
			
		||||
    - lll
 | 
			
		||||
    - gochecknoinits
 | 
			
		||||
    - gochecknoglobals
 | 
			
		||||
    - nlreturn
 | 
			
		||||
    - testpackage
 | 
			
		||||
    - funlen
 | 
			
		||||
    - godox
 | 
			
		||||
    - gocognit
 | 
			
		||||
    - whitespace
 | 
			
		||||
    - wsl
 | 
			
		||||
    - wrapcheck
 | 
			
		||||
    - testpackage
 | 
			
		||||
    - nlreturn
 | 
			
		||||
    - gomnd
 | 
			
		||||
    - exhaustive
 | 
			
		||||
    - exhaustivestruct
 | 
			
		||||
    - goerr113
 | 
			
		||||
    - wsl
 | 
			
		||||
    - whitespace
 | 
			
		||||
    - gofumpt
 | 
			
		||||
    - godot
 | 
			
		||||
    - errorlint
 | 
			
		||||
    - nestif
 | 
			
		||||
    - godox
 | 
			
		||||
    - funlen
 | 
			
		||||
    - gci
 | 
			
		||||
    - gocognit
 | 
			
		||||
    - godot
 | 
			
		||||
    - gofumpt
 | 
			
		||||
    - paralleltest
 | 
			
		||||
    - tparallel
 | 
			
		||||
    - thelper
 | 
			
		||||
    - ifshort
 | 
			
		||||
    - gomoddirectives
 | 
			
		||||
    - cyclop
 | 
			
		||||
    - forcetypeassert
 | 
			
		||||
    - ireturn
 | 
			
		||||
    - tagliatelle
 | 
			
		||||
    - varnamelen
 | 
			
		||||
    - goimports
 | 
			
		||||
    - tenv
 | 
			
		||||
    - golint
 | 
			
		||||
    - exhaustruct
 | 
			
		||||
    - nilnil
 | 
			
		||||
    - varnamelen
 | 
			
		||||
    - gci
 | 
			
		||||
    - depguard
 | 
			
		||||
    - errchkjson
 | 
			
		||||
    - inamedparam
 | 
			
		||||
    - nonamedreturns
 | 
			
		||||
    - musttag
 | 
			
		||||
    - ireturn
 | 
			
		||||
    - forcetypeassert
 | 
			
		||||
    - cyclop
 | 
			
		||||
    # deprecated linters
 | 
			
		||||
    - deadcode
 | 
			
		||||
    - interfacer
 | 
			
		||||
    - scopelint
 | 
			
		||||
    - varcheck
 | 
			
		||||
    - structcheck
 | 
			
		||||
    - golint
 | 
			
		||||
    - nosnakecase
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/github.com/go-openapi/swag/BENCHMARK.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/go-openapi/swag/BENCHMARK.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
# Benchmarks
 | 
			
		||||
 | 
			
		||||
## Name mangling utilities
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
go test -bench XXX -run XXX -benchtime 30s
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Benchmarks at b3e7a5386f996177e4808f11acb2aa93a0f660df
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
goos: linux
 | 
			
		||||
goarch: amd64
 | 
			
		||||
pkg: github.com/go-openapi/swag
 | 
			
		||||
cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
 | 
			
		||||
BenchmarkToXXXName/ToGoName-4         	  862623	     44101 ns/op	   10450 B/op	     732 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToVarName-4        	  853656	     40728 ns/op	   10468 B/op	     734 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToFileName-4       	 1268312	     27813 ns/op	    9785 B/op	     617 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToCommandName-4    	 1276322	     27903 ns/op	    9785 B/op	     617 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToHumanNameLower-4 	  895334	     40354 ns/op	   10472 B/op	     731 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToHumanNameTitle-4 	  882441	     40678 ns/op	   10566 B/op	     749 allocs/op
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Benchmarks after PR #79
 | 
			
		||||
 | 
			
		||||
~ x10 performance improvement and ~ /100 memory allocations.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
goos: linux
 | 
			
		||||
goarch: amd64
 | 
			
		||||
pkg: github.com/go-openapi/swag
 | 
			
		||||
cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
 | 
			
		||||
BenchmarkToXXXName/ToGoName-4         	 9595830	      3991 ns/op	      42 B/op	       5 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToVarName-4        	 9194276	      3984 ns/op	      62 B/op	       7 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToFileName-4       	17002711	      2123 ns/op	     147 B/op	       7 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToCommandName-4    	16772926	      2111 ns/op	     147 B/op	       7 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToHumanNameLower-4 	 9788331	      3749 ns/op	      92 B/op	       6 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToHumanNameTitle-4 	 9188260	      3941 ns/op	     104 B/op	       6 allocs/op
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
goos: linux
 | 
			
		||||
goarch: amd64
 | 
			
		||||
pkg: github.com/go-openapi/swag
 | 
			
		||||
cpu: AMD Ryzen 7 5800X 8-Core Processor             
 | 
			
		||||
BenchmarkToXXXName/ToGoName-16         	18527378	      1972 ns/op	      42 B/op	       5 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToVarName-16        	15552692	      2093 ns/op	      62 B/op	       7 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToFileName-16       	32161176	      1117 ns/op	     147 B/op	       7 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToCommandName-16    	32256634	      1137 ns/op	     147 B/op	       7 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToHumanNameLower-16 	18599661	      1946 ns/op	      92 B/op	       6 allocs/op
 | 
			
		||||
BenchmarkToXXXName/ToHumanNameTitle-16 	17581353	      2054 ns/op	     105 B/op	       6 allocs/op
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/github.com/go-openapi/swag/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/go-openapi/swag/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,7 +1,8 @@
 | 
			
		||||
# Swag [](https://travis-ci.org/go-openapi/swag) [](https://codecov.io/gh/go-openapi/swag) [](https://slackin.goswagger.io)
 | 
			
		||||
# Swag [](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/swag)
 | 
			
		||||
 | 
			
		||||
[](https://slackin.goswagger.io)
 | 
			
		||||
[](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
 | 
			
		||||
[](http://godoc.org/github.com/go-openapi/swag)
 | 
			
		||||
[](https://pkg.go.dev/github.com/go-openapi/swag)
 | 
			
		||||
[](https://goreportcard.com/report/github.com/go-openapi/swag)
 | 
			
		||||
 | 
			
		||||
Contains a bunch of helper functions for go-openapi and go-swagger projects.
 | 
			
		||||
@@ -18,4 +19,5 @@ You may also use it standalone for your projects.
 | 
			
		||||
 | 
			
		||||
This repo has only few dependencies outside of the standard library:
 | 
			
		||||
 | 
			
		||||
* YAML utilities depend on gopkg.in/yaml.v2
 | 
			
		||||
* YAML utilities depend on `gopkg.in/yaml.v3`
 | 
			
		||||
* `github.com/mailru/easyjson v0.7.7`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										202
									
								
								vendor/github.com/go-openapi/swag/initialism_index.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/go-openapi/swag/initialism_index.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
			
		||||
// 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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										105
									
								
								vendor/github.com/go-openapi/swag/loading.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/go-openapi/swag/loading.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -21,6 +21,7 @@ import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
@@ -40,43 +41,97 @@ var LoadHTTPBasicAuthPassword = ""
 | 
			
		||||
var LoadHTTPCustomHeaders = map[string]string{}
 | 
			
		||||
 | 
			
		||||
// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
 | 
			
		||||
func LoadFromFileOrHTTP(path string) ([]byte, error) {
 | 
			
		||||
	return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
 | 
			
		||||
func LoadFromFileOrHTTP(pth string) ([]byte, error) {
 | 
			
		||||
	return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(pth)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
 | 
			
		||||
// timeout arg allows for per request overriding of the request timeout
 | 
			
		||||
func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {
 | 
			
		||||
	return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path)
 | 
			
		||||
func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration) ([]byte, error) {
 | 
			
		||||
	return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(timeout))(pth)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LoadStrategy returns a loader function for a given path or uri
 | 
			
		||||
func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
 | 
			
		||||
	if strings.HasPrefix(path, "http") {
 | 
			
		||||
// LoadStrategy returns a loader function for a given path or URI.
 | 
			
		||||
//
 | 
			
		||||
// The load strategy returns the remote load for any path starting with `http`.
 | 
			
		||||
// So this works for any URI with a scheme `http` or `https`.
 | 
			
		||||
//
 | 
			
		||||
// The fallback strategy is to call the local loader.
 | 
			
		||||
//
 | 
			
		||||
// The local loader takes a local file system path (absolute or relative) as argument,
 | 
			
		||||
// or alternatively a `file://...` URI, **without host** (see also below for windows).
 | 
			
		||||
//
 | 
			
		||||
// There are a few liberalities, initially intended to be tolerant regarding the URI syntax,
 | 
			
		||||
// especially on windows.
 | 
			
		||||
//
 | 
			
		||||
// Before the local loader is called, the given path is transformed:
 | 
			
		||||
//   - percent-encoded characters are unescaped
 | 
			
		||||
//   - simple paths (e.g. `./folder/file`) are passed as-is
 | 
			
		||||
//   - on windows, occurrences of `/` are replaced by `\`, so providing a relative path such a `folder/file` works too.
 | 
			
		||||
//
 | 
			
		||||
// For paths provided as URIs with the "file" scheme, please note that:
 | 
			
		||||
//   - `file://` is simply stripped.
 | 
			
		||||
//     This means that the host part of the URI is not parsed at all.
 | 
			
		||||
//     For example, `file:///folder/file" becomes "/folder/file`,
 | 
			
		||||
//     but `file://localhost/folder/file` becomes `localhost/folder/file` on unix systems.
 | 
			
		||||
//     Similarly, `file://./folder/file` yields `./folder/file`.
 | 
			
		||||
//   - on windows, `file://...` can take a host so as to specify an UNC share location.
 | 
			
		||||
//
 | 
			
		||||
// Reminder about windows-specifics:
 | 
			
		||||
// - `file://host/folder/file` becomes an UNC path like `\\host\folder\file` (no port specification is supported)
 | 
			
		||||
// - `file:///c:/folder/file` becomes `C:\folder\file`
 | 
			
		||||
// - `file://c:/folder/file` is tolerated (without leading `/`) and becomes `c:\folder\file`
 | 
			
		||||
func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
 | 
			
		||||
	if strings.HasPrefix(pth, "http") {
 | 
			
		||||
		return remote
 | 
			
		||||
	}
 | 
			
		||||
	return func(pth string) ([]byte, error) {
 | 
			
		||||
		upth, err := pathUnescape(pth)
 | 
			
		||||
 | 
			
		||||
	return func(p string) ([]byte, error) {
 | 
			
		||||
		upth, err := url.PathUnescape(p)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if strings.HasPrefix(pth, `file://`) {
 | 
			
		||||
			if runtime.GOOS == "windows" {
 | 
			
		||||
				// support for canonical file URIs on windows.
 | 
			
		||||
				// Zero tolerance here for dodgy URIs.
 | 
			
		||||
				u, _ := url.Parse(upth)
 | 
			
		||||
				if u.Host != "" {
 | 
			
		||||
					// assume UNC name (volume share)
 | 
			
		||||
					// file://host/share/folder\... ==> \\host\share\path\folder
 | 
			
		||||
					// NOTE: UNC port not yet supported
 | 
			
		||||
					upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`)
 | 
			
		||||
				} else {
 | 
			
		||||
					// file:///c:/folder/... ==> just remove the leading slash
 | 
			
		||||
					upth = strings.TrimPrefix(upth, `file:///`)
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				upth = strings.TrimPrefix(upth, `file://`)
 | 
			
		||||
		if !strings.HasPrefix(p, `file://`) {
 | 
			
		||||
			// regular file path provided: just normalize slashes
 | 
			
		||||
			return local(filepath.FromSlash(upth))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if runtime.GOOS != "windows" {
 | 
			
		||||
			// crude processing: this leaves full URIs with a host with a (mostly) unexpected result
 | 
			
		||||
			upth = strings.TrimPrefix(upth, `file://`)
 | 
			
		||||
 | 
			
		||||
			return local(filepath.FromSlash(upth))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// windows-only pre-processing of file://... URIs
 | 
			
		||||
 | 
			
		||||
		// support for canonical file URIs on windows.
 | 
			
		||||
		u, err := url.Parse(filepath.ToSlash(upth))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if u.Host != "" {
 | 
			
		||||
			// assume UNC name (volume share)
 | 
			
		||||
			// NOTE: UNC port not yet supported
 | 
			
		||||
 | 
			
		||||
			// when the "host" segment is a drive letter:
 | 
			
		||||
			// file://C:/folder/... => C:\folder
 | 
			
		||||
			upth = path.Clean(strings.Join([]string{u.Host, u.Path}, `/`))
 | 
			
		||||
			if !strings.HasSuffix(u.Host, ":") && u.Host[0] != '.' {
 | 
			
		||||
				// tolerance: if we have a leading dot, this can't be a host
 | 
			
		||||
				// file://host/share/folder\... ==> \\host\share\path\folder
 | 
			
		||||
				upth = "//" + upth
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// no host, let's figure out if this is a drive letter
 | 
			
		||||
			upth = strings.TrimPrefix(upth, `file://`)
 | 
			
		||||
			first, _, _ := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
 | 
			
		||||
			if strings.HasSuffix(first, ":") {
 | 
			
		||||
				// drive letter in the first segment:
 | 
			
		||||
				// file:///c:/folder/... ==> strip the leading slash
 | 
			
		||||
				upth = strings.TrimPrefix(upth, `/`)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								vendor/github.com/go-openapi/swag/name_lexem.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								vendor/github.com/go-openapi/swag/name_lexem.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -14,74 +14,80 @@
 | 
			
		||||
 | 
			
		||||
package swag
 | 
			
		||||
 | 
			
		||||
import "unicode"
 | 
			
		||||
import (
 | 
			
		||||
	"unicode"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	nameLexem interface {
 | 
			
		||||
		GetUnsafeGoName() string
 | 
			
		||||
		GetOriginal() string
 | 
			
		||||
		IsInitialism() bool
 | 
			
		||||
	}
 | 
			
		||||
	lexemKind uint8
 | 
			
		||||
 | 
			
		||||
	initialismNameLexem struct {
 | 
			
		||||
	nameLexem struct {
 | 
			
		||||
		original          string
 | 
			
		||||
		matchedInitialism string
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	casualNameLexem struct {
 | 
			
		||||
		original string
 | 
			
		||||
		kind              lexemKind
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem {
 | 
			
		||||
	return &initialismNameLexem{
 | 
			
		||||
const (
 | 
			
		||||
	lexemKindCasualName lexemKind = iota
 | 
			
		||||
	lexemKindInitialismName
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func newInitialismNameLexem(original, matchedInitialism string) nameLexem {
 | 
			
		||||
	return nameLexem{
 | 
			
		||||
		kind:              lexemKindInitialismName,
 | 
			
		||||
		original:          original,
 | 
			
		||||
		matchedInitialism: matchedInitialism,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newCasualNameLexem(original string) *casualNameLexem {
 | 
			
		||||
	return &casualNameLexem{
 | 
			
		||||
func newCasualNameLexem(original string) nameLexem {
 | 
			
		||||
	return nameLexem{
 | 
			
		||||
		kind:     lexemKindCasualName,
 | 
			
		||||
		original: original,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *initialismNameLexem) GetUnsafeGoName() string {
 | 
			
		||||
	return l.matchedInitialism
 | 
			
		||||
}
 | 
			
		||||
func (l nameLexem) GetUnsafeGoName() string {
 | 
			
		||||
	if l.kind == lexemKindInitialismName {
 | 
			
		||||
		return l.matchedInitialism
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		first rune
 | 
			
		||||
		rest  string
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
func (l *casualNameLexem) GetUnsafeGoName() string {
 | 
			
		||||
	var first rune
 | 
			
		||||
	var rest string
 | 
			
		||||
	for i, orig := range l.original {
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			first = orig
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if i > 0 {
 | 
			
		||||
			rest = l.original[i:]
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(l.original) > 1 {
 | 
			
		||||
		return string(unicode.ToUpper(first)) + lower(rest)
 | 
			
		||||
		b := poolOfBuffers.BorrowBuffer(utf8.UTFMax + len(rest))
 | 
			
		||||
		defer func() {
 | 
			
		||||
			poolOfBuffers.RedeemBuffer(b)
 | 
			
		||||
		}()
 | 
			
		||||
		b.WriteRune(unicode.ToUpper(first))
 | 
			
		||||
		b.WriteString(lower(rest))
 | 
			
		||||
		return b.String()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return l.original
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *initialismNameLexem) GetOriginal() string {
 | 
			
		||||
func (l nameLexem) GetOriginal() string {
 | 
			
		||||
	return l.original
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *casualNameLexem) GetOriginal() string {
 | 
			
		||||
	return l.original
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *initialismNameLexem) IsInitialism() bool {
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *casualNameLexem) IsInitialism() bool {
 | 
			
		||||
	return false
 | 
			
		||||
func (l nameLexem) IsInitialism() bool {
 | 
			
		||||
	return l.kind == lexemKindInitialismName
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/github.com/go-openapi/swag/post_go18.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/go-openapi/swag/post_go18.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,24 +0,0 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
//go:build go1.8
 | 
			
		||||
// +build go1.8
 | 
			
		||||
 | 
			
		||||
package swag
 | 
			
		||||
 | 
			
		||||
import "net/url"
 | 
			
		||||
 | 
			
		||||
func pathUnescape(path string) (string, error) {
 | 
			
		||||
	return url.PathUnescape(path)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								vendor/github.com/go-openapi/swag/post_go19.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										68
									
								
								vendor/github.com/go-openapi/swag/post_go19.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,68 +0,0 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
//go:build go1.9
 | 
			
		||||
// +build go1.9
 | 
			
		||||
 | 
			
		||||
package swag
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 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, value interface{}) bool {
 | 
			
		||||
		k := key.(string)
 | 
			
		||||
		result = append(result, k)
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
	sort.Sort(sort.Reverse(byInitialism(result)))
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/github.com/go-openapi/swag/pre_go18.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/go-openapi/swag/pre_go18.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,24 +0,0 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
//go:build !go1.8
 | 
			
		||||
// +build !go1.8
 | 
			
		||||
 | 
			
		||||
package swag
 | 
			
		||||
 | 
			
		||||
import "net/url"
 | 
			
		||||
 | 
			
		||||
func pathUnescape(path string) (string, error) {
 | 
			
		||||
	return url.QueryUnescape(path)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								vendor/github.com/go-openapi/swag/pre_go19.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								vendor/github.com/go-openapi/swag/pre_go19.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,70 +0,0 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
//go:build !go1.9
 | 
			
		||||
// +build !go1.9
 | 
			
		||||
 | 
			
		||||
package swag
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
 | 
			
		||||
// Before go1.9, this may be implemented with a mutex on the map.
 | 
			
		||||
type indexOfInitialisms struct {
 | 
			
		||||
	getMutex *sync.Mutex
 | 
			
		||||
	index    map[string]bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newIndexOfInitialisms() *indexOfInitialisms {
 | 
			
		||||
	return &indexOfInitialisms{
 | 
			
		||||
		getMutex: new(sync.Mutex),
 | 
			
		||||
		index:    make(map[string]bool, 50),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
 | 
			
		||||
	m.getMutex.Lock()
 | 
			
		||||
	defer m.getMutex.Unlock()
 | 
			
		||||
	for k, v := range initial {
 | 
			
		||||
		m.index[k] = v
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *indexOfInitialisms) isInitialism(key string) bool {
 | 
			
		||||
	m.getMutex.Lock()
 | 
			
		||||
	defer m.getMutex.Unlock()
 | 
			
		||||
	_, ok := m.index[key]
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
 | 
			
		||||
	m.getMutex.Lock()
 | 
			
		||||
	defer m.getMutex.Unlock()
 | 
			
		||||
	m.index[key] = true
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *indexOfInitialisms) sorted() (result []string) {
 | 
			
		||||
	m.getMutex.Lock()
 | 
			
		||||
	defer m.getMutex.Unlock()
 | 
			
		||||
	for k := range m.index {
 | 
			
		||||
		result = append(result, k)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Sort(sort.Reverse(byInitialism(result)))
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										490
									
								
								vendor/github.com/go-openapi/swag/split.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										490
									
								
								vendor/github.com/go-openapi/swag/split.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,124 +15,269 @@
 | 
			
		||||
package swag
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"unicode"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var nameReplaceTable = map[rune]string{
 | 
			
		||||
	'@': "At ",
 | 
			
		||||
	'&': "And ",
 | 
			
		||||
	'|': "Pipe ",
 | 
			
		||||
	'$': "Dollar ",
 | 
			
		||||
	'!': "Bang ",
 | 
			
		||||
	'-': "",
 | 
			
		||||
	'_': "",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	splitter struct {
 | 
			
		||||
		postSplitInitialismCheck bool
 | 
			
		||||
		initialisms              []string
 | 
			
		||||
		initialismsRunes         [][]rune
 | 
			
		||||
		initialismsUpperCased    [][]rune // initialisms cached in their trimmed, upper-cased version
 | 
			
		||||
		postSplitInitialismCheck bool
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	splitterOption func(*splitter) *splitter
 | 
			
		||||
	splitterOption func(*splitter)
 | 
			
		||||
 | 
			
		||||
	initialismMatch struct {
 | 
			
		||||
		body       []rune
 | 
			
		||||
		start, end int
 | 
			
		||||
		complete   bool
 | 
			
		||||
	}
 | 
			
		||||
	initialismMatches []initialismMatch
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// split calls the splitter; splitter provides more control and post options
 | 
			
		||||
func split(str string) []string {
 | 
			
		||||
	lexems := newSplitter().split(str)
 | 
			
		||||
	result := make([]string, 0, len(lexems))
 | 
			
		||||
type (
 | 
			
		||||
	// memory pools of temporary objects.
 | 
			
		||||
	//
 | 
			
		||||
	// These are used to recycle temporarily allocated objects
 | 
			
		||||
	// and relieve the GC from undue pressure.
 | 
			
		||||
 | 
			
		||||
	for _, lexem := range lexems {
 | 
			
		||||
	matchesPool struct {
 | 
			
		||||
		*sync.Pool
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buffersPool struct {
 | 
			
		||||
		*sync.Pool
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lexemsPool struct {
 | 
			
		||||
		*sync.Pool
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	splittersPool struct {
 | 
			
		||||
		*sync.Pool
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// poolOfMatches holds temporary slices for recycling during the initialism match process
 | 
			
		||||
	poolOfMatches = matchesPool{
 | 
			
		||||
		Pool: &sync.Pool{
 | 
			
		||||
			New: func() any {
 | 
			
		||||
				s := make(initialismMatches, 0, maxAllocMatches)
 | 
			
		||||
 | 
			
		||||
				return &s
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	poolOfBuffers = buffersPool{
 | 
			
		||||
		Pool: &sync.Pool{
 | 
			
		||||
			New: func() any {
 | 
			
		||||
				return new(bytes.Buffer)
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	poolOfLexems = lexemsPool{
 | 
			
		||||
		Pool: &sync.Pool{
 | 
			
		||||
			New: func() any {
 | 
			
		||||
				s := make([]nameLexem, 0, maxAllocMatches)
 | 
			
		||||
 | 
			
		||||
				return &s
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	poolOfSplitters = splittersPool{
 | 
			
		||||
		Pool: &sync.Pool{
 | 
			
		||||
			New: func() any {
 | 
			
		||||
				s := newSplitter()
 | 
			
		||||
 | 
			
		||||
				return &s
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// nameReplaceTable finds a word representation for special characters.
 | 
			
		||||
func nameReplaceTable(r rune) (string, bool) {
 | 
			
		||||
	switch r {
 | 
			
		||||
	case '@':
 | 
			
		||||
		return "At ", true
 | 
			
		||||
	case '&':
 | 
			
		||||
		return "And ", true
 | 
			
		||||
	case '|':
 | 
			
		||||
		return "Pipe ", true
 | 
			
		||||
	case '$':
 | 
			
		||||
		return "Dollar ", true
 | 
			
		||||
	case '!':
 | 
			
		||||
		return "Bang ", true
 | 
			
		||||
	case '-':
 | 
			
		||||
		return "", true
 | 
			
		||||
	case '_':
 | 
			
		||||
		return "", true
 | 
			
		||||
	default:
 | 
			
		||||
		return "", false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// split calls the splitter.
 | 
			
		||||
//
 | 
			
		||||
// Use newSplitter for more control and options
 | 
			
		||||
func split(str string) []string {
 | 
			
		||||
	s := poolOfSplitters.BorrowSplitter()
 | 
			
		||||
	lexems := s.split(str)
 | 
			
		||||
	result := make([]string, 0, len(*lexems))
 | 
			
		||||
 | 
			
		||||
	for _, lexem := range *lexems {
 | 
			
		||||
		result = append(result, lexem.GetOriginal())
 | 
			
		||||
	}
 | 
			
		||||
	poolOfLexems.RedeemLexems(lexems)
 | 
			
		||||
	poolOfSplitters.RedeemSplitter(s)
 | 
			
		||||
 | 
			
		||||
	return result
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *splitter) split(str string) []nameLexem {
 | 
			
		||||
	return s.toNameLexems(str)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newSplitter(options ...splitterOption) *splitter {
 | 
			
		||||
	splitter := &splitter{
 | 
			
		||||
func newSplitter(options ...splitterOption) splitter {
 | 
			
		||||
	s := splitter{
 | 
			
		||||
		postSplitInitialismCheck: false,
 | 
			
		||||
		initialisms:              initialisms,
 | 
			
		||||
		initialismsRunes:         initialismsRunes,
 | 
			
		||||
		initialismsUpperCased:    initialismsUpperCased,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, option := range options {
 | 
			
		||||
		splitter = option(splitter)
 | 
			
		||||
		option(&s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return splitter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// withPostSplitInitialismCheck allows to catch initialisms after main split process
 | 
			
		||||
func withPostSplitInitialismCheck(s *splitter) *splitter {
 | 
			
		||||
	s.postSplitInitialismCheck = true
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	initialismMatch struct {
 | 
			
		||||
		start, end int
 | 
			
		||||
		body       []rune
 | 
			
		||||
		complete   bool
 | 
			
		||||
	}
 | 
			
		||||
	initialismMatches []*initialismMatch
 | 
			
		||||
)
 | 
			
		||||
// withPostSplitInitialismCheck allows to catch initialisms after main split process
 | 
			
		||||
func withPostSplitInitialismCheck(s *splitter) {
 | 
			
		||||
	s.postSplitInitialismCheck = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *splitter) toNameLexems(name string) []nameLexem {
 | 
			
		||||
func (p matchesPool) BorrowMatches() *initialismMatches {
 | 
			
		||||
	s := p.Get().(*initialismMatches)
 | 
			
		||||
	*s = (*s)[:0] // reset slice, keep allocated capacity
 | 
			
		||||
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer {
 | 
			
		||||
	s := p.Get().(*bytes.Buffer)
 | 
			
		||||
	s.Reset()
 | 
			
		||||
 | 
			
		||||
	if s.Cap() < size {
 | 
			
		||||
		s.Grow(size)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p lexemsPool) BorrowLexems() *[]nameLexem {
 | 
			
		||||
	s := p.Get().(*[]nameLexem)
 | 
			
		||||
	*s = (*s)[:0] // reset slice, keep allocated capacity
 | 
			
		||||
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p splittersPool) BorrowSplitter(options ...splitterOption) *splitter {
 | 
			
		||||
	s := p.Get().(*splitter)
 | 
			
		||||
	s.postSplitInitialismCheck = false // reset options
 | 
			
		||||
	for _, apply := range options {
 | 
			
		||||
		apply(s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p matchesPool) RedeemMatches(s *initialismMatches) {
 | 
			
		||||
	p.Put(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p buffersPool) RedeemBuffer(s *bytes.Buffer) {
 | 
			
		||||
	p.Put(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p lexemsPool) RedeemLexems(s *[]nameLexem) {
 | 
			
		||||
	p.Put(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p splittersPool) RedeemSplitter(s *splitter) {
 | 
			
		||||
	p.Put(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m initialismMatch) isZero() bool {
 | 
			
		||||
	return m.start == 0 && m.end == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s splitter) split(name string) *[]nameLexem {
 | 
			
		||||
	nameRunes := []rune(name)
 | 
			
		||||
	matches := s.gatherInitialismMatches(nameRunes)
 | 
			
		||||
	if matches == nil {
 | 
			
		||||
		return poolOfLexems.BorrowLexems()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s.mapMatchesToNameLexems(nameRunes, matches)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
 | 
			
		||||
	matches := make(initialismMatches, 0)
 | 
			
		||||
func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches {
 | 
			
		||||
	var matches *initialismMatches
 | 
			
		||||
 | 
			
		||||
	for currentRunePosition, currentRune := range nameRunes {
 | 
			
		||||
		newMatches := make(initialismMatches, 0, len(matches))
 | 
			
		||||
		// recycle these allocations as we loop over runes
 | 
			
		||||
		// with such recycling, only 2 slices should be allocated per call
 | 
			
		||||
		// instead of o(n).
 | 
			
		||||
		newMatches := poolOfMatches.BorrowMatches()
 | 
			
		||||
 | 
			
		||||
		// check current initialism matches
 | 
			
		||||
		for _, match := range matches {
 | 
			
		||||
			if keepCompleteMatch := match.complete; keepCompleteMatch {
 | 
			
		||||
				newMatches = append(newMatches, match)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// drop failed match
 | 
			
		||||
			currentMatchRune := match.body[currentRunePosition-match.start]
 | 
			
		||||
			if !s.initialismRuneEqual(currentMatchRune, currentRune) {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// try to complete ongoing match
 | 
			
		||||
			if currentRunePosition-match.start == len(match.body)-1 {
 | 
			
		||||
				// we are close; the next step is to check the symbol ahead
 | 
			
		||||
				// if it is a small letter, then it is not the end of match
 | 
			
		||||
				// but beginning of the next word
 | 
			
		||||
 | 
			
		||||
				if currentRunePosition < len(nameRunes)-1 {
 | 
			
		||||
					nextRune := nameRunes[currentRunePosition+1]
 | 
			
		||||
					if newWord := unicode.IsLower(nextRune); newWord {
 | 
			
		||||
						// oh ok, it was the start of a new word
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
		if matches != nil { // skip first iteration
 | 
			
		||||
			for _, match := range *matches {
 | 
			
		||||
				if keepCompleteMatch := match.complete; keepCompleteMatch {
 | 
			
		||||
					*newMatches = append(*newMatches, match)
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				match.complete = true
 | 
			
		||||
				match.end = currentRunePosition
 | 
			
		||||
			}
 | 
			
		||||
				// drop failed match
 | 
			
		||||
				currentMatchRune := match.body[currentRunePosition-match.start]
 | 
			
		||||
				if currentMatchRune != currentRune {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			newMatches = append(newMatches, match)
 | 
			
		||||
				// try to complete ongoing match
 | 
			
		||||
				if currentRunePosition-match.start == len(match.body)-1 {
 | 
			
		||||
					// we are close; the next step is to check the symbol ahead
 | 
			
		||||
					// if it is a small letter, then it is not the end of match
 | 
			
		||||
					// but beginning of the next word
 | 
			
		||||
 | 
			
		||||
					if currentRunePosition < len(nameRunes)-1 {
 | 
			
		||||
						nextRune := nameRunes[currentRunePosition+1]
 | 
			
		||||
						if newWord := unicode.IsLower(nextRune); newWord {
 | 
			
		||||
							// oh ok, it was the start of a new word
 | 
			
		||||
							continue
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					match.complete = true
 | 
			
		||||
					match.end = currentRunePosition
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				*newMatches = append(*newMatches, match)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// check for new initialism matches
 | 
			
		||||
		for _, initialism := range s.initialisms {
 | 
			
		||||
			initialismRunes := []rune(initialism)
 | 
			
		||||
			if s.initialismRuneEqual(initialismRunes[0], currentRune) {
 | 
			
		||||
				newMatches = append(newMatches, &initialismMatch{
 | 
			
		||||
		for i := range s.initialisms {
 | 
			
		||||
			initialismRunes := s.initialismsRunes[i]
 | 
			
		||||
			if initialismRunes[0] == currentRune {
 | 
			
		||||
				*newMatches = append(*newMatches, initialismMatch{
 | 
			
		||||
					start:    currentRunePosition,
 | 
			
		||||
					body:     initialismRunes,
 | 
			
		||||
					complete: false,
 | 
			
		||||
@@ -140,24 +285,28 @@ func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if matches != nil {
 | 
			
		||||
			poolOfMatches.RedeemMatches(matches)
 | 
			
		||||
		}
 | 
			
		||||
		matches = newMatches
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// up to the caller to redeem this last slice
 | 
			
		||||
	return matches
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem {
 | 
			
		||||
	nameLexems := make([]nameLexem, 0)
 | 
			
		||||
func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem {
 | 
			
		||||
	nameLexems := poolOfLexems.BorrowLexems()
 | 
			
		||||
 | 
			
		||||
	var lastAcceptedMatch *initialismMatch
 | 
			
		||||
	for _, match := range matches {
 | 
			
		||||
	var lastAcceptedMatch initialismMatch
 | 
			
		||||
	for _, match := range *matches {
 | 
			
		||||
		if !match.complete {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if firstMatch := lastAcceptedMatch == nil; firstMatch {
 | 
			
		||||
			nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...)
 | 
			
		||||
			nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
 | 
			
		||||
		if firstMatch := lastAcceptedMatch.isZero(); firstMatch {
 | 
			
		||||
			s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start])
 | 
			
		||||
			*nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
 | 
			
		||||
 | 
			
		||||
			lastAcceptedMatch = match
 | 
			
		||||
 | 
			
		||||
@@ -169,63 +318,66 @@ func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMa
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		middle := nameRunes[lastAcceptedMatch.end+1 : match.start]
 | 
			
		||||
		nameLexems = append(nameLexems, s.breakCasualString(middle)...)
 | 
			
		||||
		nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
 | 
			
		||||
		s.appendBrokenDownCasualString(nameLexems, middle)
 | 
			
		||||
		*nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
 | 
			
		||||
 | 
			
		||||
		lastAcceptedMatch = match
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// we have not found any accepted matches
 | 
			
		||||
	if lastAcceptedMatch == nil {
 | 
			
		||||
		return s.breakCasualString(nameRunes)
 | 
			
		||||
	if lastAcceptedMatch.isZero() {
 | 
			
		||||
		*nameLexems = (*nameLexems)[:0]
 | 
			
		||||
		s.appendBrokenDownCasualString(nameLexems, nameRunes)
 | 
			
		||||
	} else if lastAcceptedMatch.end+1 != len(nameRunes) {
 | 
			
		||||
		rest := nameRunes[lastAcceptedMatch.end+1:]
 | 
			
		||||
		s.appendBrokenDownCasualString(nameLexems, rest)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if lastAcceptedMatch.end+1 != len(nameRunes) {
 | 
			
		||||
		rest := nameRunes[lastAcceptedMatch.end+1:]
 | 
			
		||||
		nameLexems = append(nameLexems, s.breakCasualString(rest)...)
 | 
			
		||||
	}
 | 
			
		||||
	poolOfMatches.RedeemMatches(matches)
 | 
			
		||||
 | 
			
		||||
	return nameLexems
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *splitter) initialismRuneEqual(a, b rune) bool {
 | 
			
		||||
	return a == b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *splitter) breakInitialism(original string) nameLexem {
 | 
			
		||||
func (s splitter) breakInitialism(original string) nameLexem {
 | 
			
		||||
	return newInitialismNameLexem(original, original)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *splitter) breakCasualString(str []rune) []nameLexem {
 | 
			
		||||
	segments := make([]nameLexem, 0)
 | 
			
		||||
	currentSegment := ""
 | 
			
		||||
func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) {
 | 
			
		||||
	currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused
 | 
			
		||||
	defer func() {
 | 
			
		||||
		poolOfBuffers.RedeemBuffer(currentSegment)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	addCasualNameLexem := func(original string) {
 | 
			
		||||
		segments = append(segments, newCasualNameLexem(original))
 | 
			
		||||
		*segments = append(*segments, newCasualNameLexem(original))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	addInitialismNameLexem := func(original, match string) {
 | 
			
		||||
		segments = append(segments, newInitialismNameLexem(original, match))
 | 
			
		||||
		*segments = append(*segments, newInitialismNameLexem(original, match))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	addNameLexem := func(original string) {
 | 
			
		||||
		if s.postSplitInitialismCheck {
 | 
			
		||||
			for _, initialism := range s.initialisms {
 | 
			
		||||
				if upper(initialism) == upper(original) {
 | 
			
		||||
					addInitialismNameLexem(original, initialism)
 | 
			
		||||
	var addNameLexem func(string)
 | 
			
		||||
	if s.postSplitInitialismCheck {
 | 
			
		||||
		addNameLexem = func(original string) {
 | 
			
		||||
			for i := range s.initialisms {
 | 
			
		||||
				if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) {
 | 
			
		||||
					addInitialismNameLexem(original, s.initialisms[i])
 | 
			
		||||
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		addCasualNameLexem(original)
 | 
			
		||||
			addCasualNameLexem(original)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		addNameLexem = addCasualNameLexem
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, rn := range string(str) {
 | 
			
		||||
		if replace, found := nameReplaceTable[rn]; found {
 | 
			
		||||
			if currentSegment != "" {
 | 
			
		||||
				addNameLexem(currentSegment)
 | 
			
		||||
				currentSegment = ""
 | 
			
		||||
	for _, rn := range str {
 | 
			
		||||
		if replace, found := nameReplaceTable(rn); found {
 | 
			
		||||
			if currentSegment.Len() > 0 {
 | 
			
		||||
				addNameLexem(currentSegment.String())
 | 
			
		||||
				currentSegment.Reset()
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if replace != "" {
 | 
			
		||||
@@ -236,27 +388,121 @@ func (s *splitter) breakCasualString(str []rune) []nameLexem {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) {
 | 
			
		||||
			if currentSegment != "" {
 | 
			
		||||
				addNameLexem(currentSegment)
 | 
			
		||||
				currentSegment = ""
 | 
			
		||||
			if currentSegment.Len() > 0 {
 | 
			
		||||
				addNameLexem(currentSegment.String())
 | 
			
		||||
				currentSegment.Reset()
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if unicode.IsUpper(rn) {
 | 
			
		||||
			if currentSegment != "" {
 | 
			
		||||
				addNameLexem(currentSegment)
 | 
			
		||||
			if currentSegment.Len() > 0 {
 | 
			
		||||
				addNameLexem(currentSegment.String())
 | 
			
		||||
			}
 | 
			
		||||
			currentSegment = ""
 | 
			
		||||
			currentSegment.Reset()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		currentSegment += string(rn)
 | 
			
		||||
		currentSegment.WriteRune(rn)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if currentSegment != "" {
 | 
			
		||||
		addNameLexem(currentSegment)
 | 
			
		||||
	if currentSegment.Len() > 0 {
 | 
			
		||||
		addNameLexem(currentSegment.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return segments
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but
 | 
			
		||||
// it ignores leading and trailing blank spaces in the compared
 | 
			
		||||
// string.
 | 
			
		||||
//
 | 
			
		||||
// base is assumed to be composed of upper-cased runes, and be already
 | 
			
		||||
// trimmed.
 | 
			
		||||
//
 | 
			
		||||
// This code is heavily inspired from strings.EqualFold.
 | 
			
		||||
func isEqualFoldIgnoreSpace(base []rune, str string) bool {
 | 
			
		||||
	var i, baseIndex int
 | 
			
		||||
	// equivalent to b := []byte(str), but without data copy
 | 
			
		||||
	b := hackStringBytes(str)
 | 
			
		||||
 | 
			
		||||
	for i < len(b) {
 | 
			
		||||
		if c := b[i]; c < utf8.RuneSelf {
 | 
			
		||||
			// fast path for ASCII
 | 
			
		||||
			if c != ' ' && c != '\t' {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			i++
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// unicode case
 | 
			
		||||
		r, size := utf8.DecodeRune(b[i:])
 | 
			
		||||
		if !unicode.IsSpace(r) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		i += size
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if i >= len(b) {
 | 
			
		||||
		return len(base) == 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, baseRune := range base {
 | 
			
		||||
		if i >= len(b) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if c := b[i]; c < utf8.RuneSelf {
 | 
			
		||||
			// single byte rune case (ASCII)
 | 
			
		||||
			if baseRune >= utf8.RuneSelf {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			baseChar := byte(baseRune)
 | 
			
		||||
			if c != baseChar &&
 | 
			
		||||
				!('a' <= c && c <= 'z' && c-'a'+'A' == baseChar) {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			baseIndex++
 | 
			
		||||
			i++
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// unicode case
 | 
			
		||||
		r, size := utf8.DecodeRune(b[i:])
 | 
			
		||||
		if unicode.ToUpper(r) != baseRune {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		baseIndex++
 | 
			
		||||
		i += size
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if baseIndex != len(base) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// all passed: now we should only have blanks
 | 
			
		||||
	for i < len(b) {
 | 
			
		||||
		if c := b[i]; c < utf8.RuneSelf {
 | 
			
		||||
			// fast path for ASCII
 | 
			
		||||
			if c != ' ' && c != '\t' {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
			i++
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// unicode case
 | 
			
		||||
		r, size := utf8.DecodeRune(b[i:])
 | 
			
		||||
		if !unicode.IsSpace(r) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		i += size
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/github.com/go-openapi/swag/string_bytes.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/go-openapi/swag/string_bytes.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
package swag
 | 
			
		||||
 | 
			
		||||
import "unsafe"
 | 
			
		||||
 | 
			
		||||
// hackStringBytes returns the (unsafe) underlying bytes slice of a string.
 | 
			
		||||
func hackStringBytes(str string) []byte {
 | 
			
		||||
	return unsafe.Slice(unsafe.StringData(str), len(str))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										210
									
								
								vendor/github.com/go-openapi/swag/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										210
									
								
								vendor/github.com/go-openapi/swag/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,76 +18,25 @@ import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// commonInitialisms are common acronyms that are kept as whole uppercased words.
 | 
			
		||||
var commonInitialisms *indexOfInitialisms
 | 
			
		||||
 | 
			
		||||
// initialisms is a slice of sorted initialisms
 | 
			
		||||
var initialisms []string
 | 
			
		||||
 | 
			
		||||
var isInitialism func(string) bool
 | 
			
		||||
 | 
			
		||||
// GoNamePrefixFunc sets an optional rule to prefix go names
 | 
			
		||||
// which do not start with a letter.
 | 
			
		||||
//
 | 
			
		||||
// The prefix function is assumed to return a string that starts with an upper case letter.
 | 
			
		||||
//
 | 
			
		||||
// e.g. to help convert "123" into "{prefix}123"
 | 
			
		||||
//
 | 
			
		||||
// The default is to prefix with "X"
 | 
			
		||||
var GoNamePrefixFunc func(string) string
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
 | 
			
		||||
	var 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,
 | 
			
		||||
func prefixFunc(name, in string) string {
 | 
			
		||||
	if GoNamePrefixFunc == nil {
 | 
			
		||||
		return "X" + in
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// a thread-safe index of initialisms
 | 
			
		||||
	commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
 | 
			
		||||
	initialisms = commonInitialisms.sorted()
 | 
			
		||||
 | 
			
		||||
	// a test function
 | 
			
		||||
	isInitialism = commonInitialisms.isInitialism
 | 
			
		||||
	return GoNamePrefixFunc(name) + in
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -156,25 +105,9 @@ func SplitByFormat(data, format string) []string {
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Removes leading whitespaces
 | 
			
		||||
func trim(str string) string {
 | 
			
		||||
	return strings.Trim(str, " ")
 | 
			
		||||
	return strings.TrimSpace(str)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Shortcut to strings.ToUpper()
 | 
			
		||||
@@ -188,15 +121,20 @@ func lower(str string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Camelize an uppercased word
 | 
			
		||||
func Camelize(word string) (camelized string) {
 | 
			
		||||
func Camelize(word string) string {
 | 
			
		||||
	camelized := poolOfBuffers.BorrowBuffer(len(word))
 | 
			
		||||
	defer func() {
 | 
			
		||||
		poolOfBuffers.RedeemBuffer(camelized)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	for pos, ru := range []rune(word) {
 | 
			
		||||
		if pos > 0 {
 | 
			
		||||
			camelized += string(unicode.ToLower(ru))
 | 
			
		||||
			camelized.WriteRune(unicode.ToLower(ru))
 | 
			
		||||
		} else {
 | 
			
		||||
			camelized += string(unicode.ToUpper(ru))
 | 
			
		||||
			camelized.WriteRune(unicode.ToUpper(ru))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
	return camelized.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToFileName lowercases and underscores a go type name
 | 
			
		||||
@@ -224,33 +162,40 @@ func ToCommandName(name string) string {
 | 
			
		||||
 | 
			
		||||
// ToHumanNameLower represents a code name as a human series of words
 | 
			
		||||
func ToHumanNameLower(name string) string {
 | 
			
		||||
	in := newSplitter(withPostSplitInitialismCheck).split(name)
 | 
			
		||||
	out := make([]string, 0, len(in))
 | 
			
		||||
	s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
 | 
			
		||||
	in := s.split(name)
 | 
			
		||||
	poolOfSplitters.RedeemSplitter(s)
 | 
			
		||||
	out := make([]string, 0, len(*in))
 | 
			
		||||
 | 
			
		||||
	for _, w := range in {
 | 
			
		||||
	for _, w := range *in {
 | 
			
		||||
		if !w.IsInitialism() {
 | 
			
		||||
			out = append(out, lower(w.GetOriginal()))
 | 
			
		||||
		} else {
 | 
			
		||||
			out = append(out, w.GetOriginal())
 | 
			
		||||
			out = append(out, trim(w.GetOriginal()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	poolOfLexems.RedeemLexems(in)
 | 
			
		||||
 | 
			
		||||
	return strings.Join(out, " ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
 | 
			
		||||
func ToHumanNameTitle(name string) string {
 | 
			
		||||
	in := newSplitter(withPostSplitInitialismCheck).split(name)
 | 
			
		||||
	s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
 | 
			
		||||
	in := s.split(name)
 | 
			
		||||
	poolOfSplitters.RedeemSplitter(s)
 | 
			
		||||
 | 
			
		||||
	out := make([]string, 0, len(in))
 | 
			
		||||
	for _, w := range in {
 | 
			
		||||
		original := w.GetOriginal()
 | 
			
		||||
	out := make([]string, 0, len(*in))
 | 
			
		||||
	for _, w := range *in {
 | 
			
		||||
		original := trim(w.GetOriginal())
 | 
			
		||||
		if !w.IsInitialism() {
 | 
			
		||||
			out = append(out, Camelize(original))
 | 
			
		||||
		} else {
 | 
			
		||||
			out = append(out, original)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	poolOfLexems.RedeemLexems(in)
 | 
			
		||||
 | 
			
		||||
	return strings.Join(out, " ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -264,7 +209,7 @@ func ToJSONName(name string) string {
 | 
			
		||||
			out = append(out, lower(w))
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		out = append(out, Camelize(w))
 | 
			
		||||
		out = append(out, Camelize(trim(w)))
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(out, "")
 | 
			
		||||
}
 | 
			
		||||
@@ -283,35 +228,70 @@ func ToVarName(name string) string {
 | 
			
		||||
 | 
			
		||||
// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
 | 
			
		||||
func ToGoName(name string) string {
 | 
			
		||||
	lexems := newSplitter(withPostSplitInitialismCheck).split(name)
 | 
			
		||||
	s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
 | 
			
		||||
	lexems := s.split(name)
 | 
			
		||||
	poolOfSplitters.RedeemSplitter(s)
 | 
			
		||||
	defer func() {
 | 
			
		||||
		poolOfLexems.RedeemLexems(lexems)
 | 
			
		||||
	}()
 | 
			
		||||
	lexemes := *lexems
 | 
			
		||||
 | 
			
		||||
	result := ""
 | 
			
		||||
	for _, lexem := range lexems {
 | 
			
		||||
	if len(lexemes) == 0 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result := poolOfBuffers.BorrowBuffer(len(name))
 | 
			
		||||
	defer func() {
 | 
			
		||||
		poolOfBuffers.RedeemBuffer(result)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	// check if not starting with a letter, upper case
 | 
			
		||||
	firstPart := lexemes[0].GetUnsafeGoName()
 | 
			
		||||
	if lexemes[0].IsInitialism() {
 | 
			
		||||
		firstPart = upper(firstPart)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c := firstPart[0]; c < utf8.RuneSelf {
 | 
			
		||||
		// ASCII
 | 
			
		||||
		switch {
 | 
			
		||||
		case 'A' <= c && c <= 'Z':
 | 
			
		||||
			result.WriteString(firstPart)
 | 
			
		||||
		case 'a' <= c && c <= 'z':
 | 
			
		||||
			result.WriteByte(c - 'a' + 'A')
 | 
			
		||||
			result.WriteString(firstPart[1:])
 | 
			
		||||
		default:
 | 
			
		||||
			result.WriteString(prefixFunc(name, firstPart))
 | 
			
		||||
			// NOTE: no longer check if prefixFunc returns a string that starts with uppercase:
 | 
			
		||||
			// assume this is always the case
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// unicode
 | 
			
		||||
		firstRune, _ := utf8.DecodeRuneInString(firstPart)
 | 
			
		||||
		switch {
 | 
			
		||||
		case !unicode.IsLetter(firstRune):
 | 
			
		||||
			result.WriteString(prefixFunc(name, firstPart))
 | 
			
		||||
		case !unicode.IsUpper(firstRune):
 | 
			
		||||
			result.WriteString(prefixFunc(name, firstPart))
 | 
			
		||||
			/*
 | 
			
		||||
				result.WriteRune(unicode.ToUpper(firstRune))
 | 
			
		||||
				result.WriteString(firstPart[offset:])
 | 
			
		||||
			*/
 | 
			
		||||
		default:
 | 
			
		||||
			result.WriteString(firstPart)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, lexem := range lexemes[1:] {
 | 
			
		||||
		goName := lexem.GetUnsafeGoName()
 | 
			
		||||
 | 
			
		||||
		// to support old behavior
 | 
			
		||||
		if lexem.IsInitialism() {
 | 
			
		||||
			goName = upper(goName)
 | 
			
		||||
		}
 | 
			
		||||
		result += goName
 | 
			
		||||
		result.WriteString(goName)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(result) > 0 {
 | 
			
		||||
		// Only prefix with X when the first character isn't an ascii letter
 | 
			
		||||
		first := []rune(result)[0]
 | 
			
		||||
		if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) {
 | 
			
		||||
			if GoNamePrefixFunc == nil {
 | 
			
		||||
				return "X" + result
 | 
			
		||||
			}
 | 
			
		||||
			result = GoNamePrefixFunc(name) + result
 | 
			
		||||
		}
 | 
			
		||||
		first = []rune(result)[0]
 | 
			
		||||
		if unicode.IsLetter(first) && !unicode.IsUpper(first) {
 | 
			
		||||
			result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result
 | 
			
		||||
	return result.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContainsStrings searches a slice of strings for a case-sensitive match
 | 
			
		||||
@@ -343,7 +323,7 @@ type zeroable interface {
 | 
			
		||||
func IsZero(data interface{}) bool {
 | 
			
		||||
	v := reflect.ValueOf(data)
 | 
			
		||||
	// check for nil data
 | 
			
		||||
	switch v.Kind() {
 | 
			
		||||
	switch v.Kind() { //nolint:exhaustive
 | 
			
		||||
	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
 | 
			
		||||
		if v.IsNil() {
 | 
			
		||||
			return true
 | 
			
		||||
@@ -356,7 +336,7 @@ func IsZero(data interface{}) bool {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// continue with slightly more complex reflection
 | 
			
		||||
	switch v.Kind() {
 | 
			
		||||
	switch v.Kind() { //nolint:exhaustive
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		return v.Len() == 0
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
@@ -376,16 +356,6 @@ func IsZero(data interface{}) bool {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CommandLineOptionsGroup represents a group of user-defined command line options
 | 
			
		||||
type CommandLineOptionsGroup struct {
 | 
			
		||||
	ShortDescription string
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/github.com/go-openapi/swag/yaml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/go-openapi/swag/yaml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -16,8 +16,11 @@ package swag
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/mailru/easyjson/jlexer"
 | 
			
		||||
@@ -48,7 +51,7 @@ func BytesToYAMLDoc(data []byte) (interface{}, error) {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode {
 | 
			
		||||
		return nil, fmt.Errorf("only YAML documents that are objects are supported")
 | 
			
		||||
		return nil, errors.New("only YAML documents that are objects are supported")
 | 
			
		||||
	}
 | 
			
		||||
	return &document, nil
 | 
			
		||||
}
 | 
			
		||||
@@ -147,7 +150,7 @@ func yamlScalar(node *yaml.Node) (interface{}, error) {
 | 
			
		||||
	case yamlTimestamp:
 | 
			
		||||
		return node.Value, nil
 | 
			
		||||
	case yamlNull:
 | 
			
		||||
		return nil, nil
 | 
			
		||||
		return nil, nil //nolint:nilnil
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag())
 | 
			
		||||
	}
 | 
			
		||||
@@ -245,7 +248,27 @@ func (s JSONMapSlice) MarshalYAML() (interface{}, error) {
 | 
			
		||||
	return yaml.Marshal(&n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isNil(input interface{}) bool {
 | 
			
		||||
	if input == nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	kind := reflect.TypeOf(input).Kind()
 | 
			
		||||
	switch kind { //nolint:exhaustive
 | 
			
		||||
	case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
 | 
			
		||||
		return reflect.ValueOf(input).IsNil()
 | 
			
		||||
	default:
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func json2yaml(item interface{}) (*yaml.Node, error) {
 | 
			
		||||
	if isNil(item) {
 | 
			
		||||
		return &yaml.Node{
 | 
			
		||||
			Kind:  yaml.ScalarNode,
 | 
			
		||||
			Value: "null",
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch val := item.(type) {
 | 
			
		||||
	case JSONMapSlice:
 | 
			
		||||
		var n yaml.Node
 | 
			
		||||
@@ -265,7 +288,14 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
 | 
			
		||||
	case map[string]interface{}:
 | 
			
		||||
		var n yaml.Node
 | 
			
		||||
		n.Kind = yaml.MappingNode
 | 
			
		||||
		for k, v := range val {
 | 
			
		||||
		keys := make([]string, 0, len(val))
 | 
			
		||||
		for k := range val {
 | 
			
		||||
			keys = append(keys, k)
 | 
			
		||||
		}
 | 
			
		||||
		sort.Strings(keys)
 | 
			
		||||
 | 
			
		||||
		for _, k := range keys {
 | 
			
		||||
			v := val[k]
 | 
			
		||||
			childNode, err := json2yaml(v)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
@@ -318,8 +348,9 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
 | 
			
		||||
			Tag:   yamlBoolScalar,
 | 
			
		||||
			Value: strconv.FormatBool(val),
 | 
			
		||||
		}, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("unhandled type: %T", val)
 | 
			
		||||
	}
 | 
			
		||||
	return nil, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user