aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/ettle
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2022-09-05 14:27:54 +0200
committerGitHub <noreply@github.com>2022-09-05 12:27:54 +0000
commitb2f2446b46bf02821d90ebedadae2bf7ae0e880e (patch)
tree923cf42842918d6bebca1d6bbdc08abed54d274d /vendor/github.com/ettle
parente6654faff4bcca4be92e9a8596fd4b77f747c39e (diff)
go.mod, vendor: update (#3358)
* go.mod, vendor: remove unnecessary dependencies Commands: 1. go mod tidy 2. go mod vendor * go.mod, vendor: update cloud.google.com/go Commands: 1. go get -u cloud.google.com/go 2. go mod tidy 3. go mod vendor * go.mod, vendor: update cloud.google.com/* Commands: 1. go get -u cloud.google.com/storage cloud.google.com/logging 2. go mod tidy 3. go mod vendor * go.mod, .golangci.yml, vendor: update *lint* Commands: 1. go get -u golang.org/x/tools github.com/golangci/golangci-lint@v1.47.0 2. go mod tidy 3. go mod vendor 4. edit .golangci.yml to suppress new errors (resolved in the same PR later) * all: fix lint errors hash.go: copy() recommended by gosimple parse.go: ent is never nil verifier.go: signal.Notify() with unbuffered channel is bad. Have no idea why. * .golangci.yml: adjust godot rules check-all is deprecated, but still work if you're hesitating too - I'll remove this commit
Diffstat (limited to 'vendor/github.com/ettle')
-rw-r--r--vendor/github.com/ettle/strcase/.gitignore18
-rw-r--r--vendor/github.com/ettle/strcase/.golangci.yml88
-rw-r--r--vendor/github.com/ettle/strcase/.readme.tmpl80
-rw-r--r--vendor/github.com/ettle/strcase/LICENSE21
-rw-r--r--vendor/github.com/ettle/strcase/Makefile16
-rw-r--r--vendor/github.com/ettle/strcase/README.md542
-rw-r--r--vendor/github.com/ettle/strcase/caser.go87
-rw-r--r--vendor/github.com/ettle/strcase/convert.go297
-rw-r--r--vendor/github.com/ettle/strcase/doc.go155
-rw-r--r--vendor/github.com/ettle/strcase/go.mod5
-rw-r--r--vendor/github.com/ettle/strcase/go.sum11
-rw-r--r--vendor/github.com/ettle/strcase/initialism.go43
-rw-r--r--vendor/github.com/ettle/strcase/split.go164
-rw-r--r--vendor/github.com/ettle/strcase/strcase.go81
-rw-r--r--vendor/github.com/ettle/strcase/unicode.go48
15 files changed, 1656 insertions, 0 deletions
diff --git a/vendor/github.com/ettle/strcase/.gitignore b/vendor/github.com/ettle/strcase/.gitignore
new file mode 100644
index 000000000..54bc1fbff
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/.gitignore
@@ -0,0 +1,18 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# CPU and memory profiles
+*.prof
+
+# Dependency directories
+vendor/
diff --git a/vendor/github.com/ettle/strcase/.golangci.yml b/vendor/github.com/ettle/strcase/.golangci.yml
new file mode 100644
index 000000000..4d31fcc5b
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/.golangci.yml
@@ -0,0 +1,88 @@
+linters-settings:
+ dupl:
+ threshold: 100
+ gocyclo:
+ min-complexity: 15
+ gocritic:
+ enabled-tags:
+ - diagnostic
+ - experimental
+ - opinionated
+ - performance
+ - style
+ disabled-checks:
+ - ifElseChain
+ - whyNoLint
+ - wrapperFunc
+ golint:
+ min-confidence: 0.5
+ govet:
+ check-shadowing: true
+ lll:
+ line-length: 140
+ maligned:
+ suggest-new: true
+ misspell:
+ locale: US
+ nolintlint:
+ allow-leading-space: false
+ allow-unused: false
+ require-specific: true
+
+ require-explanation: true
+ allow-no-explanation:
+ - gocyclo
+
+linters:
+ disable-all: true
+ enable:
+ - bodyclose
+ - deadcode
+ - depguard
+ - dogsled
+ - dupl
+ - errcheck
+ - gochecknoinits
+ - gocritic
+ - gocyclo
+ - gofmt
+ - goimports
+ - golint
+ - goprintffuncname
+ - gosec
+ - gosimple
+ - govet
+ - ineffassign
+ - interfacer
+ - lll
+ - misspell
+ - nakedret
+ - nolintlint
+ - rowserrcheck
+ - staticcheck
+ - structcheck
+ - stylecheck
+ - typecheck
+ - unconvert
+ - unparam
+ - unused
+ - varcheck
+ - whitespace
+
+ # don't enable:
+ # - asciicheck
+ # - gochecknoglobals
+ # - gocognit
+ # - godot
+ # - godox
+ # - goerr113
+ # - maligned
+ # - nestif
+ # - prealloc
+ # - testpackage
+ # - wsl
+
+issues:
+ exclude-use-default: false
+ max-issues-per-linter: 0
+ max-same-issues: 0
diff --git a/vendor/github.com/ettle/strcase/.readme.tmpl b/vendor/github.com/ettle/strcase/.readme.tmpl
new file mode 100644
index 000000000..135765c40
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/.readme.tmpl
@@ -0,0 +1,80 @@
+{{with .PDoc}}
+# Go Strcase
+
+[![Go Report Card](https://goreportcard.com/badge/github.com/ettle/strcase)](https://goreportcard.com/report/github.com/ettle/strcase)
+[![Coverage](http://gocover.io/_badge/github.com/ettle/strcase?0)](http://gocover.io/github.com/ettle/strcase)
+[![GoDoc](https://godoc.org/github.com/ettle/strcase?status.svg)](https://pkg.go.dev/github.com/ettle/strcase)
+
+Convert strings to `snake_case`, `camelCase`, `PascalCase`, `kebab-case` and more! Supports Go initialisms, customization, and Unicode.
+
+`import "{{.ImportPath}}"`
+
+## <a name="pkg-overview">Overview</a>
+{{comment_md .Doc}}
+{{example_html $ ""}}
+
+## <a name="pkg-index">Index</a>{{if .Consts}}
+* [Constants](#pkg-constants){{end}}{{if .Vars}}
+* [Variables](#pkg-variables){{end}}{{- range .Funcs -}}{{$name_html := html .Name}}
+* [{{node_html $ .Decl false | sanitize}}](#{{$name_html}}){{- end}}{{- range .Types}}{{$tname_html := html .Name}}
+* [type {{$tname_html}}](#{{$tname_html}}){{- range .Funcs}}{{$name_html := html .Name}}
+ * [{{node_html $ .Decl false | sanitize}}](#{{$name_html}}){{- end}}{{- range .Methods}}{{$name_html := html .Name}}
+ * [{{node_html $ .Decl false | sanitize}}](#{{$tname_html}}.{{$name_html}}){{- end}}{{- end}}{{- if $.Notes}}{{- range $marker, $item := $.Notes}}
+* [{{noteTitle $marker | html}}s](#pkg-note-{{$marker}}){{end}}{{end}}
+{{if $.Examples}}
+#### <a name="pkg-examples">Examples</a>{{- range $.Examples}}
+* [{{example_name .Name}}](#example_{{.Name}}){{- end}}{{- end}}
+
+{{with .Consts}}## <a name="pkg-constants">Constants</a>
+{{range .}}{{node $ .Decl | pre}}
+{{comment_md .Doc}}{{end}}{{end}}
+{{with .Vars}}## <a name="pkg-variables">Variables</a>
+{{range .}}{{node $ .Decl | pre}}
+{{comment_md .Doc}}{{end}}{{end}}
+
+{{range .Funcs}}{{$name_html := html .Name}}## <a name="{{$name_html}}">func</a> [{{$name_html}}]({{gh_url $ .Decl}})
+{{node $ .Decl | pre}}
+{{comment_md .Doc}}
+{{example_html $ .Name}}
+{{callgraph_html $ "" .Name}}{{end}}
+{{range .Types}}{{$tname := .Name}}{{$tname_html := html .Name}}## <a name="{{$tname_html}}">type</a> [{{$tname_html}}]({{gh_url $ .Decl}})
+{{node $ .Decl | pre}}
+{{comment_md .Doc}}{{range .Consts}}
+{{node $ .Decl | pre }}
+{{comment_md .Doc}}{{end}}{{range .Vars}}
+{{node $ .Decl | pre }}
+{{comment_md .Doc}}{{end}}
+
+{{example_html $ $tname}}
+{{implements_html $ $tname}}
+{{methodset_html $ $tname}}
+
+{{range .Funcs}}{{$name_html := html .Name}}### <a name="{{$name_html}}">func</a> [{{$name_html}}]({{gh_url $ .Decl}})
+{{node $ .Decl | pre}}
+{{comment_md .Doc}}
+{{example_html $ .Name}}{{end}}
+{{callgraph_html $ "" .Name}}
+
+{{range .Methods}}{{$name_html := html .Name}}### <a name="{{$tname_html}}.{{$name_html}}">func</a> ({{md .Recv}}) [{{$name_html}}]({{gh_url $ .Decl}})
+{{node $ .Decl | pre}}
+{{comment_md .Doc}}
+{{$name := printf "%s_%s" $tname .Name}}{{example_html $ $name}}
+{{callgraph_html $ .Recv .Name}}
+{{end}}{{end}}{{end}}
+
+{{with $.Notes}}
+{{range $marker, $content := .}}
+## <a name="pkg-note-{{$marker}}">{{noteTitle $marker | html}}s
+<ul style="list-style: none; padding: 0;">
+{{range .}}
+<li><a href="{{gh_url $ .}}">&#x261e;</a> {{html .Body}}</li>
+{{end}}
+</ul>
+{{end}}
+{{end}}
+{{if .Dirs}}
+## <a name="Subdirectories">Subdirectories</a>
+{{range $.Dirs.List}}
+{{indent .Depth}}* [{{.Name | html}}]({{print "./" .Path}}){{if .Synopsis}} {{ .Synopsis}}{{end -}}
+{{end}}
+{{end}}
diff --git a/vendor/github.com/ettle/strcase/LICENSE b/vendor/github.com/ettle/strcase/LICENSE
new file mode 100644
index 000000000..4f0116be2
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Liyan David Chang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/ettle/strcase/Makefile b/vendor/github.com/ettle/strcase/Makefile
new file mode 100644
index 000000000..462f8b473
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/Makefile
@@ -0,0 +1,16 @@
+.PHONY: benchmark docs lint test
+
+docs:
+ which godoc2ghmd || ( go get github.com/DevotedHealth/godoc2ghmd && go mod tidy )
+ godoc2ghmd -template .readme.tmpl github.com/ettle/strcase > README.md
+
+test:
+ go test -cover ./...
+
+lint:
+ which golangci-lint || ( go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0 && go mod tidy )
+ golangci-lint run
+ golangci-lint run benchmark/*.go
+
+benchmark:
+ cd benchmark && go test -bench=. -test.benchmem && go mod tidy
diff --git a/vendor/github.com/ettle/strcase/README.md b/vendor/github.com/ettle/strcase/README.md
new file mode 100644
index 000000000..ee165e3e5
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/README.md
@@ -0,0 +1,542 @@
+
+# Go Strcase
+
+[![Go Report Card](https://goreportcard.com/badge/github.com/ettle/strcase)](https://goreportcard.com/report/github.com/ettle/strcase)
+[![Coverage](http://gocover.io/_badge/github.com/ettle/strcase?0)](http://gocover.io/github.com/ettle/strcase)
+[![GoDoc](https://godoc.org/github.com/ettle/strcase?status.svg)](https://pkg.go.dev/github.com/ettle/strcase)
+
+Convert strings to `snake_case`, `camelCase`, `PascalCase`, `kebab-case` and more! Supports Go initialisms, customization, and Unicode.
+
+`import "github.com/ettle/strcase"`
+
+## <a name="pkg-overview">Overview</a>
+Package strcase is a package for converting strings into various word cases
+(e.g. snake_case, camelCase)
+
+
+ go get -u github.com/ettle/strcase
+
+Example usage
+
+
+ strcase.ToSnake("Hello World") // hello_world
+ strcase.ToSNAKE("Hello World") // HELLO_WORLD
+
+ strcase.ToKebab("helloWorld") // hello-world
+ strcase.ToKEBAB("helloWorld") // HELLO-WORLD
+
+ strcase.ToPascal("hello-world") // HelloWorld
+ strcase.ToCamel("hello-world") // helloWorld
+
+ // Handle odd cases
+ strcase.ToSnake("FOOBar") // foo_bar
+
+ // Support Go initialisms
+ strcase.ToGoCamel("http_response") // HTTPResponse
+
+ // Specify case and delimiter
+ strcase.ToCase("HelloWorld", strcase.UpperCase, '.') // HELLO.WORLD
+
+### Why this package
+String strcase is pretty straight forward and there are a number of methods to
+do it. This package is fully featured, more customizable, better tested, and
+faster* than other packages and what you would probably whip up yourself.
+
+### Unicode support
+We work for with unicode strings and pay very little performance penalty for it
+as we optimized for the common use case of ASCII only strings.
+
+### Customization
+You can create a custom caser that changes the behavior to what you want. This
+customization also reduces the pressure for us to change the default behavior
+which means that things are more stable for everyone involved. The goal is to
+make the common path easy and fast, while making the uncommon path possible.
+
+
+ c := NewCaser(
+ // Use Go's default initialisms e.g. ID, HTML
+ true,
+ // Override initialisms (e.g. don't initialize HTML but initialize SSL
+ map[string]bool{"SSL": true, "HTML": false},
+ // Write your own custom SplitFn
+ //
+ NewSplitFn(
+ []rune{'*', '.', ','},
+ SplitCase,
+ SplitAcronym,
+ PreserveNumberFormatting,
+ SplitBeforeNumber,
+ SplitAfterNumber,
+ ))
+ assert.Equal(t, "http_200", c.ToSnake("http200"))
+
+### Initialism support
+By default, we use the golint intialisms list. You can customize and override
+the initialisms if you wish to add additional ones, such as "SSL" or "CMS" or
+domain specific ones to your industry.
+
+
+ ToGoCamel("http_response") // HTTPResponse
+ ToGoSnake("http_response") // HTTP_response
+
+### Test coverage
+We have a wide ranging test suite to make sure that we understand our behavior.
+Test coverage isn't everything, but we aim for 100% coverage.
+
+### Fast
+Optimized to reduce memory allocations with Builder. Benchmarked and optimized
+around common cases.
+
+We're on par with the fastest packages (that have less features) and much
+faster than others. We also benchmarked against code snippets. Using string
+builders to reduce memory allocation and reordering boolean checks for the
+common cases have a large performance impact.
+
+Hopefully I was fair to each library and happy to rerun benchmarks differently
+or reword my commentary based on suggestions or updates.
+
+
+ // This package
+ // Go intialisms and custom casers are slower
+ BenchmarkToTitle-4 992491 1559 ns/op 32 B/op 1 allocs/op
+ BenchmarkToSnake-4 1000000 1475 ns/op 32 B/op 1 allocs/op
+ BenchmarkToSNAKE-4 1000000 1609 ns/op 32 B/op 1 allocs/op
+ BenchmarkToGoSnake-4 275010 3697 ns/op 44 B/op 4 allocs/op
+ BenchmarkToCustomCaser-4 342704 4191 ns/op 56 B/op 4 allocs/op
+
+ // Segment has very fast snake case and camel case libraries
+ // No features or customization, but very very fast
+ BenchmarkSegment-4 1303809 938 ns/op 16 B/op 1 allocs/op
+
+ // Stdlib strings.Title for comparison, even though it only splits on spaces
+ BenchmarkToTitleStrings-4 1213467 1164 ns/op 16 B/op 1 allocs/op
+
+ // Other libraries or code snippets
+ // - Most are slower, by up to an order of magnitude
+ // - None support initialisms or customization
+ // - Some generate only camelCase or snake_case
+ // - Many lack unicode support
+ BenchmarkToSnakeStoewer-4 973200 2075 ns/op 64 B/op 2 allocs/op
+ // Copying small rune arrays is slow
+ BenchmarkToSnakeSiongui-4 264315 4229 ns/op 48 B/op 10 allocs/op
+ BenchmarkGoValidator-4 206811 5152 ns/op 184 B/op 9 allocs/op
+ // String alloction is slow
+ BenchmarkToSnakeFatih-4 82675 12280 ns/op 392 B/op 26 allocs/op
+ BenchmarkToSnakeIanColeman-4 83276 13903 ns/op 145 B/op 13 allocs/op
+ // Regexp is slow
+ BenchmarkToSnakeGolangPrograms-4 74448 18586 ns/op 176 B/op 11 allocs/op
+
+ // These results aren't a surprise - my initial version of this library was
+ // painfully slow. I think most of us, without spending some time with
+ // profilers and benchmarks, would write also something on the slower side.
+
+### Why not this package
+If every nanosecond matters and this is used in a tight loop, use segment.io's
+libraries (<a href="https://github.com/segmentio/go-snakecase">https://github.com/segmentio/go-snakecase</a> and
+<a href="https://github.com/segmentio/go-camelcase">https://github.com/segmentio/go-camelcase</a>). They lack features, but make up for
+it by being blazing fast. Alternatively, if you need your code to work slightly
+differently, fork them and tailor it for your use case.
+
+If you don't like having external imports, I get it. This package only imports
+packages for testing, otherwise it only uses the standard library. If that's
+not enough, you can use this repo as the foundation for your own. MIT Licensed.
+
+This package is still relatively new and while I've used it for a while
+personally, it doesn't have the miles that other packages do. I've tested this
+code agains't their test cases to make sure that there aren't any surprises.
+
+### Migrating from other packages
+If you are migrating from from another package, you may find slight differences
+in output. To reduce the delta, you may find it helpful to use the following
+custom casers to mimic the behavior of the other package.
+
+
+ // From <a href="https://github.com/iancoleman/strcase">https://github.com/iancoleman/strcase</a>
+ var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-', '.'}, SplitCase, SplitAcronym, SplitBeforeNumber))
+
+ // From <a href="https://github.com/stoewer/go-strcase">https://github.com/stoewer/go-strcase</a>
+ var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-'}, SplitCase), SplitAcronym)
+
+
+
+
+## <a name="pkg-index">Index</a>
+* [func ToCamel(s string) string](#ToCamel)
+* [func ToCase(s string, wordCase WordCase, delimiter rune) string](#ToCase)
+* [func ToGoCamel(s string) string](#ToGoCamel)
+* [func ToGoCase(s string, wordCase WordCase, delimiter rune) string](#ToGoCase)
+* [func ToGoKebab(s string) string](#ToGoKebab)
+* [func ToGoPascal(s string) string](#ToGoPascal)
+* [func ToGoSnake(s string) string](#ToGoSnake)
+* [func ToKEBAB(s string) string](#ToKEBAB)
+* [func ToKebab(s string) string](#ToKebab)
+* [func ToPascal(s string) string](#ToPascal)
+* [func ToSNAKE(s string) string](#ToSNAKE)
+* [func ToSnake(s string) string](#ToSnake)
+* [type Caser](#Caser)
+ * [func NewCaser(goInitialisms bool, initialismOverrides map[string]bool, splitFn SplitFn) *Caser](#NewCaser)
+ * [func (c *Caser) ToCamel(s string) string](#Caser.ToCamel)
+ * [func (c *Caser) ToCase(s string, wordCase WordCase, delimiter rune) string](#Caser.ToCase)
+ * [func (c *Caser) ToKEBAB(s string) string](#Caser.ToKEBAB)
+ * [func (c *Caser) ToKebab(s string) string](#Caser.ToKebab)
+ * [func (c *Caser) ToPascal(s string) string](#Caser.ToPascal)
+ * [func (c *Caser) ToSNAKE(s string) string](#Caser.ToSNAKE)
+ * [func (c *Caser) ToSnake(s string) string](#Caser.ToSnake)
+* [type SplitAction](#SplitAction)
+* [type SplitFn](#SplitFn)
+ * [func NewSplitFn(delimiters []rune, splitOptions ...SplitOption) SplitFn](#NewSplitFn)
+* [type SplitOption](#SplitOption)
+* [type WordCase](#WordCase)
+
+
+
+
+
+## <a name="ToCamel">func</a> [ToCamel](./strcase.go#L57)
+``` go
+func ToCamel(s string) string
+```
+ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case).
+Also known as lowerCamelCase or mixedCase.
+
+
+
+## <a name="ToCase">func</a> [ToCase](./strcase.go#L70)
+``` go
+func ToCase(s string, wordCase WordCase, delimiter rune) string
+```
+ToCase returns words in given case and delimiter.
+
+
+
+## <a name="ToGoCamel">func</a> [ToGoCamel](./strcase.go#L65)
+``` go
+func ToGoCamel(s string) string
+```
+ToGoCamel returns words in camelCase (capitalized words concatenated together, with first word lower case).
+Also known as lowerCamelCase or mixedCase.
+
+Respects Go's common initialisms (e.g. httpResponse -> HTTPResponse).
+
+
+
+## <a name="ToGoCase">func</a> [ToGoCase](./strcase.go#L77)
+``` go
+func ToGoCase(s string, wordCase WordCase, delimiter rune) string
+```
+ToGoCase returns words in given case and delimiter.
+
+Respects Go's common initialisms (e.g. httpResponse -> HTTPResponse).
+
+
+
+## <a name="ToGoKebab">func</a> [ToGoKebab](./strcase.go#L31)
+``` go
+func ToGoKebab(s string) string
+```
+ToGoKebab returns words in kebab-case (lower case words with dashes).
+Also known as dash-case.
+
+Respects Go's common initialisms (e.g. http-response -> HTTP-response).
+
+
+
+## <a name="ToGoPascal">func</a> [ToGoPascal](./strcase.go#L51)
+``` go
+func ToGoPascal(s string) string
+```
+ToGoPascal returns words in PascalCase (capitalized words concatenated together).
+Also known as UpperPascalCase.
+
+Respects Go's common initialisms (e.g. HttpResponse -> HTTPResponse).
+
+
+
+## <a name="ToGoSnake">func</a> [ToGoSnake](./strcase.go#L11)
+``` go
+func ToGoSnake(s string) string
+```
+ToGoSnake returns words in snake_case (lower case words with underscores).
+
+Respects Go's common initialisms (e.g. http_response -> HTTP_response).
+
+
+
+## <a name="ToKEBAB">func</a> [ToKEBAB](./strcase.go#L37)
+``` go
+func ToKEBAB(s string) string
+```
+ToKEBAB returns words in KEBAB-CASE (upper case words with dashes).
+Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE.
+
+
+
+## <a name="ToKebab">func</a> [ToKebab](./strcase.go#L23)
+``` go
+func ToKebab(s string) string
+```
+ToKebab returns words in kebab-case (lower case words with dashes).
+Also known as dash-case.
+
+
+
+## <a name="ToPascal">func</a> [ToPascal](./strcase.go#L43)
+``` go
+func ToPascal(s string) string
+```
+ToPascal returns words in PascalCase (capitalized words concatenated together).
+Also known as UpperPascalCase.
+
+
+
+## <a name="ToSNAKE">func</a> [ToSNAKE](./strcase.go#L17)
+``` go
+func ToSNAKE(s string) string
+```
+ToSNAKE returns words in SNAKE_CASE (upper case words with underscores).
+Also known as SCREAMING_SNAKE_CASE or UPPER_CASE.
+
+
+
+## <a name="ToSnake">func</a> [ToSnake](./strcase.go#L4)
+``` go
+func ToSnake(s string) string
+```
+ToSnake returns words in snake_case (lower case words with underscores).
+
+
+
+
+## <a name="Caser">type</a> [Caser](./caser.go#L4-L7)
+``` go
+type Caser struct {
+ // contains filtered or unexported fields
+}
+
+```
+Caser allows for customization of parsing and intialisms
+
+
+
+
+
+
+
+### <a name="NewCaser">func</a> [NewCaser](./caser.go#L24)
+``` go
+func NewCaser(goInitialisms bool, initialismOverrides map[string]bool, splitFn SplitFn) *Caser
+```
+NewCaser returns a configured Caser.
+
+A Caser should be created when you want fine grained control over how the words are split.
+
+
+ Notes on function arguments
+
+ goInitialisms: Whether to use Golint's intialisms
+
+ initialismOverrides: A mapping of extra initialisms
+ Keys must be in ALL CAPS. Merged with Golint's if goInitialisms is set.
+ Setting a key to false will override Golint's.
+
+ splitFn: How to separate words
+ Override the default split function. Consider using NewSplitFn to
+ configure one instead of writing your own.
+
+
+
+
+
+### <a name="Caser.ToCamel">func</a> (\*Caser) [ToCamel](./caser.go#L80)
+``` go
+func (c *Caser) ToCamel(s string) string
+```
+ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case).
+Also known as lowerCamelCase or mixedCase.
+
+
+
+
+### <a name="Caser.ToCase">func</a> (\*Caser) [ToCase](./caser.go#L85)
+``` go
+func (c *Caser) ToCase(s string, wordCase WordCase, delimiter rune) string
+```
+ToCase returns words with a given case and delimiter.
+
+
+
+
+### <a name="Caser.ToKEBAB">func</a> (\*Caser) [ToKEBAB](./caser.go#L68)
+``` go
+func (c *Caser) ToKEBAB(s string) string
+```
+ToKEBAB returns words in KEBAB-CASE (upper case words with dashes).
+Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE.
+
+
+
+
+### <a name="Caser.ToKebab">func</a> (\*Caser) [ToKebab](./caser.go#L62)
+``` go
+func (c *Caser) ToKebab(s string) string
+```
+ToKebab returns words in kebab-case (lower case words with dashes).
+Also known as dash-case.
+
+
+
+
+### <a name="Caser.ToPascal">func</a> (\*Caser) [ToPascal](./caser.go#L74)
+``` go
+func (c *Caser) ToPascal(s string) string
+```
+ToPascal returns words in PascalCase (capitalized words concatenated together).
+Also known as UpperPascalCase.
+
+
+
+
+### <a name="Caser.ToSNAKE">func</a> (\*Caser) [ToSNAKE](./caser.go#L56)
+``` go
+func (c *Caser) ToSNAKE(s string) string
+```
+ToSNAKE returns words in SNAKE_CASE (upper case words with underscores).
+Also known as SCREAMING_SNAKE_CASE or UPPER_CASE.
+
+
+
+
+### <a name="Caser.ToSnake">func</a> (\*Caser) [ToSnake](./caser.go#L50)
+``` go
+func (c *Caser) ToSnake(s string) string
+```
+ToSnake returns words in snake_case (lower case words with underscores).
+
+
+
+
+## <a name="SplitAction">type</a> [SplitAction](./split.go#L110)
+``` go
+type SplitAction int
+```
+SplitAction defines if and how to split a string
+
+
+``` go
+const (
+ // Noop - Continue to next character
+ Noop SplitAction = iota
+ // Split - Split between words
+ // e.g. to split between wordsWithoutDelimiters
+ Split
+ // SkipSplit - Split the word and drop the character
+ // e.g. to split words with delimiters
+ SkipSplit
+ // Skip - Remove the character completely
+ Skip
+)
+```
+
+
+
+
+
+
+
+
+
+## <a name="SplitFn">type</a> [SplitFn](./split.go#L6)
+``` go
+type SplitFn func(prev, curr, next rune) SplitAction
+```
+SplitFn defines how to split a string into words
+
+
+
+
+
+
+
+### <a name="NewSplitFn">func</a> [NewSplitFn](./split.go#L14-L17)
+``` go
+func NewSplitFn(
+ delimiters []rune,
+ splitOptions ...SplitOption,
+) SplitFn
+```
+NewSplitFn returns a SplitFn based on the options provided.
+
+NewSplitFn covers the majority of common options that other strcase
+libraries provide and should allow you to simply create a custom caser.
+For more complicated use cases, feel free to write your own SplitFn
+nolint:gocyclo
+
+
+
+
+
+## <a name="SplitOption">type</a> [SplitOption](./split.go#L93)
+``` go
+type SplitOption int
+```
+SplitOption are options that allow for configuring NewSplitFn
+
+
+``` go
+const (
+ // SplitCase - FooBar -> Foo_Bar
+ SplitCase SplitOption = iota
+ // SplitAcronym - FOOBar -> Foo_Bar
+ // It won't preserve FOO's case. If you want, you can set the Caser's initialisms so FOO will be in all caps
+ SplitAcronym
+ // SplitBeforeNumber - port80 -> port_80
+ SplitBeforeNumber
+ // SplitAfterNumber - 200status -> 200_status
+ SplitAfterNumber
+ // PreserveNumberFormatting - a.b.2,000.3.c -> a_b_2,000.3_c
+ PreserveNumberFormatting
+)
+```
+
+
+
+
+
+
+
+
+
+## <a name="WordCase">type</a> [WordCase](./convert.go#L6)
+``` go
+type WordCase int
+```
+WordCase is an enumeration of the ways to format a word.
+
+
+``` go
+const (
+ // Original - Preserve the original input strcase
+ Original WordCase = iota
+ // LowerCase - All letters lower cased (example)
+ LowerCase
+ // UpperCase - All letters upper cased (EXAMPLE)
+ UpperCase
+ // TitleCase - Only first letter upper cased (Example)
+ TitleCase
+ // CamelCase - TitleCase except lower case first word (exampleText)
+ CamelCase
+)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/ettle/strcase/caser.go b/vendor/github.com/ettle/strcase/caser.go
new file mode 100644
index 000000000..891a67189
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/caser.go
@@ -0,0 +1,87 @@
+package strcase
+
+// Caser allows for customization of parsing and intialisms
+type Caser struct {
+ initialisms map[string]bool
+ splitFn SplitFn
+}
+
+// NewCaser returns a configured Caser.
+//
+// A Caser should be created when you want fine grained control over how the words are split.
+//
+// Notes on function arguments
+//
+// goInitialisms: Whether to use Golint's intialisms
+//
+// initialismOverrides: A mapping of extra initialisms
+// Keys must be in ALL CAPS. Merged with Golint's if goInitialisms is set.
+// Setting a key to false will override Golint's.
+//
+// splitFn: How to separate words
+// Override the default split function. Consider using NewSplitFn to
+// configure one instead of writing your own.
+func NewCaser(goInitialisms bool, initialismOverrides map[string]bool, splitFn SplitFn) *Caser {
+ c := &Caser{
+ initialisms: golintInitialisms,
+ splitFn: splitFn,
+ }
+
+ if c.splitFn == nil {
+ c.splitFn = defaultSplitFn
+ }
+
+ if goInitialisms && initialismOverrides != nil {
+ c.initialisms = map[string]bool{}
+ for k, v := range golintInitialisms {
+ c.initialisms[k] = v
+ }
+ for k, v := range initialismOverrides {
+ c.initialisms[k] = v
+ }
+ } else if !goInitialisms {
+ c.initialisms = initialismOverrides
+ }
+
+ return c
+}
+
+// ToSnake returns words in snake_case (lower case words with underscores).
+func (c *Caser) ToSnake(s string) string {
+ return convert(s, c.splitFn, '_', LowerCase, c.initialisms)
+}
+
+// ToSNAKE returns words in SNAKE_CASE (upper case words with underscores).
+// Also known as SCREAMING_SNAKE_CASE or UPPER_CASE.
+func (c *Caser) ToSNAKE(s string) string {
+ return convert(s, c.splitFn, '_', UpperCase, c.initialisms)
+}
+
+// ToKebab returns words in kebab-case (lower case words with dashes).
+// Also known as dash-case.
+func (c *Caser) ToKebab(s string) string {
+ return convert(s, c.splitFn, '-', LowerCase, c.initialisms)
+}
+
+// ToKEBAB returns words in KEBAB-CASE (upper case words with dashes).
+// Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE.
+func (c *Caser) ToKEBAB(s string) string {
+ return convert(s, c.splitFn, '-', UpperCase, c.initialisms)
+}
+
+// ToPascal returns words in PascalCase (capitalized words concatenated together).
+// Also known as UpperPascalCase.
+func (c *Caser) ToPascal(s string) string {
+ return convert(s, c.splitFn, '\x00', TitleCase, c.initialisms)
+}
+
+// ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case).
+// Also known as lowerCamelCase or mixedCase.
+func (c *Caser) ToCamel(s string) string {
+ return convert(s, c.splitFn, '\x00', CamelCase, c.initialisms)
+}
+
+// ToCase returns words with a given case and delimiter.
+func (c *Caser) ToCase(s string, wordCase WordCase, delimiter rune) string {
+ return convert(s, c.splitFn, delimiter, wordCase, c.initialisms)
+}
diff --git a/vendor/github.com/ettle/strcase/convert.go b/vendor/github.com/ettle/strcase/convert.go
new file mode 100644
index 000000000..70fedb144
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/convert.go
@@ -0,0 +1,297 @@
+package strcase
+
+import "strings"
+
+// WordCase is an enumeration of the ways to format a word.
+type WordCase int
+
+const (
+ // Original - Preserve the original input strcase
+ Original WordCase = iota
+ // LowerCase - All letters lower cased (example)
+ LowerCase
+ // UpperCase - All letters upper cased (EXAMPLE)
+ UpperCase
+ // TitleCase - Only first letter upper cased (Example)
+ TitleCase
+ // CamelCase - TitleCase except lower case first word (exampleText)
+ // Notably, even if the first word is an initialism, it will be lower
+ // cased. This is important for code generators where capital letters
+ // mean exported functions. i.e. jsonString(), not JSONString()
+ CamelCase
+)
+
+// We have 3 convert functions for performance reasons
+// The general convert could handle everything, but is not optimized
+//
+// The other two functions are optimized for the general use cases - that is the non-custom caser functions
+// Case 1: Any Case and supports Go Initialisms
+// Case 2: UpperCase words, which don't need to support initialisms since everything is in upper case
+
+// convertWithoutInitialims only works for to UpperCase and LowerCase
+//nolint:gocyclo
+func convertWithoutInitialisms(input string, delimiter rune, wordCase WordCase) string {
+ input = strings.TrimSpace(input)
+ runes := []rune(input)
+ if len(runes) == 0 {
+ return ""
+ }
+
+ var b strings.Builder
+ b.Grow(len(input) * 2) // In case we need to write delimiters where they weren't before
+
+ var prev, curr rune
+ next := runes[0] // 0 length will have already returned so safe to index
+ inWord := false
+ firstWord := true
+ for i := 0; i < len(runes); i++ {
+ prev = curr
+ curr = next
+ if i+1 == len(runes) {
+ next = 0
+ } else {
+ next = runes[i+1]
+ }
+
+ switch defaultSplitFn(prev, curr, next) {
+ case SkipSplit:
+ if inWord && delimiter != 0 {
+ b.WriteRune(delimiter)
+ }
+ inWord = false
+ continue
+ case Split:
+ if inWord && delimiter != 0 {
+ b.WriteRune(delimiter)
+ }
+ inWord = false
+ }
+ switch wordCase {
+ case UpperCase:
+ b.WriteRune(toUpper(curr))
+ case LowerCase:
+ b.WriteRune(toLower(curr))
+ case TitleCase:
+ if inWord {
+ b.WriteRune(toLower(curr))
+ } else {
+ b.WriteRune(toUpper(curr))
+ }
+ case CamelCase:
+ if inWord {
+ b.WriteRune(toLower(curr))
+ } else if firstWord {
+ b.WriteRune(toLower(curr))
+ firstWord = false
+ } else {
+ b.WriteRune(toUpper(curr))
+ }
+ default:
+ // Must be original case
+ b.WriteRune(curr)
+ }
+ inWord = inWord || true
+ }
+ return b.String()
+}
+
+// convertWithGoInitialisms changes a input string to a certain case with a
+// delimiter, respecting go initialisms but not skip runes
+//nolint:gocyclo
+func convertWithGoInitialisms(input string, delimiter rune, wordCase WordCase) string {
+ input = strings.TrimSpace(input)
+ runes := []rune(input)
+ if len(runes) == 0 {
+ return ""
+ }
+
+ var b strings.Builder
+ b.Grow(len(input) * 2) // In case we need to write delimiters where they weren't before
+
+ firstWord := true
+
+ addWord := func(start, end int) {
+ if start == end {
+ return
+ }
+
+ if !firstWord && delimiter != 0 {
+ b.WriteRune(delimiter)
+ }
+
+ // Don't bother with initialisms if the word is longer than 5
+ // A quick proxy to avoid the extra memory allocations
+ if end-start <= 5 {
+ key := strings.ToUpper(string(runes[start:end]))
+ if golintInitialisms[key] {
+ if !firstWord || wordCase != CamelCase {
+ b.WriteString(key)
+ firstWord = false
+ return
+ }
+ }
+ }
+
+ for i := start; i < end; i++ {
+ r := runes[i]
+ switch wordCase {
+ case UpperCase:
+ panic("use convertWithoutInitialisms instead")
+ case LowerCase:
+ b.WriteRune(toLower(r))
+ case TitleCase:
+ if i == start {
+ b.WriteRune(toUpper(r))
+ } else {
+ b.WriteRune(toLower(r))
+ }
+ case CamelCase:
+ if !firstWord && i == start {
+ b.WriteRune(toUpper(r))
+ } else {
+ b.WriteRune(toLower(r))
+ }
+ default:
+ b.WriteRune(r)
+ }
+ }
+ firstWord = false
+ }
+
+ var prev, curr rune
+ next := runes[0] // 0 length will have already returned so safe to index
+ wordStart := 0
+ for i := 0; i < len(runes); i++ {
+ prev = curr
+ curr = next
+ if i+1 == len(runes) {
+ next = 0
+ } else {
+ next = runes[i+1]
+ }
+
+ switch defaultSplitFn(prev, curr, next) {
+ case Split:
+ addWord(wordStart, i)
+ wordStart = i
+ case SkipSplit:
+ addWord(wordStart, i)
+ wordStart = i + 1
+ }
+ }
+
+ if wordStart != len(runes) {
+ addWord(wordStart, len(runes))
+ }
+ return b.String()
+}
+
+// convert changes a input string to a certain case with a delimiter,
+// respecting arbitrary initialisms and skip characters
+//nolint:gocyclo
+func convert(input string, fn SplitFn, delimiter rune, wordCase WordCase,
+ initialisms map[string]bool) string {
+ input = strings.TrimSpace(input)
+ runes := []rune(input)
+ if len(runes) == 0 {
+ return ""
+ }
+
+ var b strings.Builder
+ b.Grow(len(input) * 2) // In case we need to write delimiters where they weren't before
+
+ firstWord := true
+ var skipIndexes []int
+
+ addWord := func(start, end int) {
+ // If you have nothing good to say, say nothing at all
+ if start == end || len(skipIndexes) == end-start {
+ skipIndexes = nil
+ return
+ }
+
+ // If you have something to say, start with a delimiter
+ if !firstWord && delimiter != 0 {
+ b.WriteRune(delimiter)
+ }
+
+ // Check if you're an initialism
+ // Note - we don't check skip characters here since initialisms
+ // will probably never have junk characters in between
+ // I'm open to it if there is a use case
+ if initialisms != nil {
+ var word strings.Builder
+ for i := start; i < end; i++ {
+ word.WriteRune(toUpper(runes[i]))
+ }
+ key := word.String()
+ if initialisms[key] {
+ if !firstWord || wordCase != CamelCase {
+ b.WriteString(key)
+ firstWord = false
+ return
+ }
+ }
+ }
+
+ skipIdx := 0
+ for i := start; i < end; i++ {
+ if len(skipIndexes) > 0 && skipIdx < len(skipIndexes) && i == skipIndexes[skipIdx] {
+ skipIdx++
+ continue
+ }
+ r := runes[i]
+ switch wordCase {
+ case UpperCase:
+ b.WriteRune(toUpper(r))
+ case LowerCase:
+ b.WriteRune(toLower(r))
+ case TitleCase:
+ if i == start {
+ b.WriteRune(toUpper(r))
+ } else {
+ b.WriteRune(toLower(r))
+ }
+ case CamelCase:
+ if !firstWord && i == start {
+ b.WriteRune(toUpper(r))
+ } else {
+ b.WriteRune(toLower(r))
+ }
+ default:
+ b.WriteRune(r)
+ }
+ }
+ firstWord = false
+ skipIndexes = nil
+ }
+
+ var prev, curr rune
+ next := runes[0] // 0 length will have already returned so safe to index
+ wordStart := 0
+ for i := 0; i < len(runes); i++ {
+ prev = curr
+ curr = next
+ if i+1 == len(runes) {
+ next = 0
+ } else {
+ next = runes[i+1]
+ }
+
+ switch fn(prev, curr, next) {
+ case Skip:
+ skipIndexes = append(skipIndexes, i)
+ case Split:
+ addWord(wordStart, i)
+ wordStart = i
+ case SkipSplit:
+ addWord(wordStart, i)
+ wordStart = i + 1
+ }
+ }
+
+ if wordStart != len(runes) {
+ addWord(wordStart, len(runes))
+ }
+ return b.String()
+}
diff --git a/vendor/github.com/ettle/strcase/doc.go b/vendor/github.com/ettle/strcase/doc.go
new file mode 100644
index 000000000..b898a4e45
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/doc.go
@@ -0,0 +1,155 @@
+/*
+Package strcase is a package for converting strings into various word cases
+(e.g. snake_case, camelCase)
+
+ go get -u github.com/ettle/strcase
+
+Example usage
+
+ strcase.ToSnake("Hello World") // hello_world
+ strcase.ToSNAKE("Hello World") // HELLO_WORLD
+
+ strcase.ToKebab("helloWorld") // hello-world
+ strcase.ToKEBAB("helloWorld") // HELLO-WORLD
+
+ strcase.ToPascal("hello-world") // HelloWorld
+ strcase.ToCamel("hello-world") // helloWorld
+
+ // Handle odd cases
+ strcase.ToSnake("FOOBar") // foo_bar
+
+ // Support Go initialisms
+ strcase.ToGoPascal("http_response") // HTTPResponse
+
+ // Specify case and delimiter
+ strcase.ToCase("HelloWorld", strcase.UpperCase, '.') // HELLO.WORLD
+
+Why this package
+
+String strcase is pretty straight forward and there are a number of methods to
+do it. This package is fully featured, more customizable, better tested, and
+faster* than other packages and what you would probably whip up yourself.
+
+Unicode support
+
+We work for with unicode strings and pay very little performance penalty for it
+as we optimized for the common use case of ASCII only strings.
+
+Customization
+
+You can create a custom caser that changes the behavior to what you want. This
+customization also reduces the pressure for us to change the default behavior
+which means that things are more stable for everyone involved. The goal is to
+make the common path easy and fast, while making the uncommon path possible.
+
+ c := NewCaser(
+ // Use Go's default initialisms e.g. ID, HTML
+ true,
+ // Override initialisms (e.g. don't initialize HTML but initialize SSL
+ map[string]bool{"SSL": true, "HTML": false},
+ // Write your own custom SplitFn
+ //
+ NewSplitFn(
+ []rune{'*', '.', ','},
+ SplitCase,
+ SplitAcronym,
+ PreserveNumberFormatting,
+ SplitBeforeNumber,
+ SplitAfterNumber,
+ ))
+ assert.Equal(t, "http_200", c.ToSnake("http200"))
+
+Initialism support
+
+By default, we use the golint intialisms list. You can customize and override
+the initialisms if you wish to add additional ones, such as "SSL" or "CMS" or
+domain specific ones to your industry.
+
+ ToGoPascal("http_response") // HTTPResponse
+ ToGoSnake("http_response") // HTTP_response
+
+Test coverage
+
+We have a wide ranging test suite to make sure that we understand our behavior.
+Test coverage isn't everything, but we aim for 100% coverage.
+
+Fast
+
+Optimized to reduce memory allocations with Builder. Benchmarked and optimized
+around common cases.
+
+We're on par with the fastest packages (that have less features) and much
+faster than others. We also benchmarked against code snippets. Using string
+builders to reduce memory allocation and reordering boolean checks for the
+common cases have a large performance impact.
+
+Hopefully I was fair to each library and happy to rerun benchmarks differently
+or reword my commentary based on suggestions or updates.
+
+ // This package - faster then almost all libraries
+ // Initialisms are more complicated and slightly slower, but still faster then other libraries that do less
+ BenchmarkToTitle-4 7821166 221 ns/op 32 B/op 1 allocs/op
+ BenchmarkToSnake-4 9378589 202 ns/op 32 B/op 1 allocs/op
+ BenchmarkToSNAKE-4 6174453 223 ns/op 32 B/op 1 allocs/op
+ BenchmarkToGoSnake-4 3114266 434 ns/op 44 B/op 4 allocs/op
+ BenchmarkToCustomCaser-4 2973855 448 ns/op 56 B/op 4 allocs/op
+
+ // Segment has very fast snake case and camel case libraries
+ // No features or customization, but very very fast
+ BenchmarkSegment-4 24003495 64.9 ns/op 16 B/op 1 allocs/op
+
+ // Stdlib strings.Title for comparison, even though it only splits on spaces
+ BenchmarkToTitleStrings-4 11259376 161 ns/op 16 B/op 1 allocs/op
+
+ // Other libraries or code snippets
+ // - Most are slower, by up to an order of magnitude
+ // - None support initialisms or customization
+ // - Some generate only camelCase or snake_case
+ // - Many lack unicode support
+ BenchmarkToSnakeStoewer-4 7103268 297 ns/op 64 B/op 2 allocs/op
+ // Copying small rune arrays is slow
+ BenchmarkToSnakeSiongui-4 3710768 413 ns/op 48 B/op 10 allocs/op
+ BenchmarkGoValidator-4 2416479 1049 ns/op 184 B/op 9 allocs/op
+ // String alloction is slow
+ BenchmarkToSnakeFatih-4 1000000 2407 ns/op 624 B/op 26 allocs/op
+ BenchmarkToSnakeIanColeman-4 1005766 1426 ns/op 160 B/op 13 allocs/op
+ // Regexp is slow
+ BenchmarkToSnakeGolangPrograms-4 614689 2237 ns/op 225 B/op 11 allocs/op
+
+
+
+ // These results aren't a surprise - my initial version of this library was
+ // painfully slow. I think most of us, without spending some time with
+ // profilers and benchmarks, would write also something on the slower side.
+
+
+Why not this package
+
+If every nanosecond matters and this is used in a tight loop, use segment.io's
+libraries (https://github.com/segmentio/go-snakecase and
+https://github.com/segmentio/go-camelcase). They lack features, but make up for
+it by being blazing fast. Alternatively, if you need your code to work slightly
+differently, fork them and tailor it for your use case.
+
+If you don't like having external imports, I get it. This package only imports
+packages for testing, otherwise it only uses the standard library. If that's
+not enough, you can use this repo as the foundation for your own. MIT Licensed.
+
+This package is still relatively new and while I've used it for a while
+personally, it doesn't have the miles that other packages do. I've tested this
+code agains't their test cases to make sure that there aren't any surprises.
+
+Migrating from other packages
+
+If you are migrating from from another package, you may find slight differences
+in output. To reduce the delta, you may find it helpful to use the following
+custom casers to mimic the behavior of the other package.
+
+ // From https://github.com/iancoleman/strcase
+ var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-', '.'}, SplitCase, SplitAcronym, SplitBeforeNumber))
+
+ // From https://github.com/stoewer/go-strcase
+ var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-'}, SplitCase), SplitAcronym)
+
+*/
+package strcase
diff --git a/vendor/github.com/ettle/strcase/go.mod b/vendor/github.com/ettle/strcase/go.mod
new file mode 100644
index 000000000..0219bfaa0
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/go.mod
@@ -0,0 +1,5 @@
+module github.com/ettle/strcase
+
+go 1.12
+
+require github.com/stretchr/testify v1.5.1
diff --git a/vendor/github.com/ettle/strcase/go.sum b/vendor/github.com/ettle/strcase/go.sum
new file mode 100644
index 000000000..331fa6982
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/go.sum
@@ -0,0 +1,11 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/ettle/strcase/initialism.go b/vendor/github.com/ettle/strcase/initialism.go
new file mode 100644
index 000000000..3c313d3e9
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/initialism.go
@@ -0,0 +1,43 @@
+package strcase
+
+// golintInitialisms are the golint initialisms
+var golintInitialisms = map[string]bool{
+ "ACL": true,
+ "API": true,
+ "ASCII": true,
+ "CPU": true,
+ "CSS": true,
+ "DNS": true,
+ "EOF": true,
+ "GUID": true,
+ "HTML": true,
+ "HTTP": true,
+ "HTTPS": true,
+ "ID": true,
+ "IP": true,
+ "JSON": true,
+ "LHS": 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,
+}
diff --git a/vendor/github.com/ettle/strcase/split.go b/vendor/github.com/ettle/strcase/split.go
new file mode 100644
index 000000000..84381106b
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/split.go
@@ -0,0 +1,164 @@
+package strcase
+
+import "unicode"
+
+// SplitFn defines how to split a string into words
+type SplitFn func(prev, curr, next rune) SplitAction
+
+// NewSplitFn returns a SplitFn based on the options provided.
+//
+// NewSplitFn covers the majority of common options that other strcase
+// libraries provide and should allow you to simply create a custom caser.
+// For more complicated use cases, feel free to write your own SplitFn
+//nolint:gocyclo
+func NewSplitFn(
+ delimiters []rune,
+ splitOptions ...SplitOption,
+) SplitFn {
+ var splitCase, splitAcronym, splitBeforeNumber, splitAfterNumber, preserveNumberFormatting bool
+
+ for _, option := range splitOptions {
+ switch option {
+ case SplitCase:
+ splitCase = true
+ case SplitAcronym:
+ splitAcronym = true
+ case SplitBeforeNumber:
+ splitBeforeNumber = true
+ case SplitAfterNumber:
+ splitAfterNumber = true
+ case PreserveNumberFormatting:
+ preserveNumberFormatting = true
+ }
+ }
+
+ return func(prev, curr, next rune) SplitAction {
+ // The most common case will be that it's just a letter
+ // There are safe cases to process
+ if isLower(curr) && !isNumber(prev) {
+ return Noop
+ }
+ if isUpper(prev) && isUpper(curr) && isUpper(next) {
+ return Noop
+ }
+
+ if preserveNumberFormatting {
+ if (curr == '.' || curr == ',') &&
+ isNumber(prev) && isNumber(next) {
+ return Noop
+ }
+ }
+
+ if unicode.IsSpace(curr) {
+ return SkipSplit
+ }
+ for _, d := range delimiters {
+ if curr == d {
+ return SkipSplit
+ }
+ }
+
+ if splitBeforeNumber {
+ if isNumber(curr) && !isNumber(prev) {
+ if preserveNumberFormatting && (prev == '.' || prev == ',') {
+ return Noop
+ }
+ return Split
+ }
+ }
+
+ if splitAfterNumber {
+ if isNumber(prev) && !isNumber(curr) {
+ return Split
+ }
+ }
+
+ if splitCase {
+ if !isUpper(prev) && isUpper(curr) {
+ return Split
+ }
+ }
+
+ if splitAcronym {
+ if isUpper(prev) && isUpper(curr) && isLower(next) {
+ return Split
+ }
+ }
+
+ return Noop
+ }
+}
+
+// SplitOption are options that allow for configuring NewSplitFn
+type SplitOption int
+
+const (
+ // SplitCase - FooBar -> Foo_Bar
+ SplitCase SplitOption = iota
+ // SplitAcronym - FOOBar -> Foo_Bar
+ // It won't preserve FOO's case. If you want, you can set the Caser's initialisms so FOO will be in all caps
+ SplitAcronym
+ // SplitBeforeNumber - port80 -> port_80
+ SplitBeforeNumber
+ // SplitAfterNumber - 200status -> 200_status
+ SplitAfterNumber
+ // PreserveNumberFormatting - a.b.2,000.3.c -> a_b_2,000.3_c
+ PreserveNumberFormatting
+)
+
+// SplitAction defines if and how to split a string
+type SplitAction int
+
+const (
+ // Noop - Continue to next character
+ Noop SplitAction = iota
+ // Split - Split between words
+ // e.g. to split between wordsWithoutDelimiters
+ Split
+ // SkipSplit - Split the word and drop the character
+ // e.g. to split words with delimiters
+ SkipSplit
+ // Skip - Remove the character completely
+ Skip
+)
+
+//nolint:gocyclo
+func defaultSplitFn(prev, curr, next rune) SplitAction {
+ // The most common case will be that it's just a letter so let lowercase letters return early since we know what they should do
+ if isLower(curr) {
+ return Noop
+ }
+ // Delimiters are _, -, ., and unicode spaces
+ // Handle . lower down as it needs to happen after number exceptions
+ if curr == '_' || curr == '-' || isSpace(curr) {
+ return SkipSplit
+ }
+
+ if isUpper(curr) {
+ if isLower(prev) {
+ // fooBar
+ return Split
+ } else if isUpper(prev) && isLower(next) {
+ // FOOBar
+ return Split
+ }
+ }
+
+ // Do numeric exceptions last to avoid perf penalty
+ if unicode.IsNumber(prev) {
+ // v4.3 is not split
+ if (curr == '.' || curr == ',') && unicode.IsNumber(next) {
+ return Noop
+ }
+ if !unicode.IsNumber(curr) && curr != '.' {
+ return Split
+ }
+ }
+ // While period is a default delimiter, keep it down here to avoid
+ // penalty for other delimiters
+ if curr == '.' {
+ return SkipSplit
+ }
+
+ return Noop
+}
diff --git a/vendor/github.com/ettle/strcase/strcase.go b/vendor/github.com/ettle/strcase/strcase.go
new file mode 100644
index 000000000..46b4f7a68
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/strcase.go
@@ -0,0 +1,81 @@
+package strcase
+
+// ToSnake returns words in snake_case (lower case words with underscores).
+func ToSnake(s string) string {
+ return convertWithoutInitialisms(s, '_', LowerCase)
+}
+
+// ToGoSnake returns words in snake_case (lower case words with underscores).
+//
+// Respects Go's common initialisms (e.g. http_response -> HTTP_response).
+func ToGoSnake(s string) string {
+ return convertWithGoInitialisms(s, '_', LowerCase)
+}
+
+// ToSNAKE returns words in SNAKE_CASE (upper case words with underscores).
+// Also known as SCREAMING_SNAKE_CASE or UPPER_CASE.
+func ToSNAKE(s string) string {
+ return convertWithoutInitialisms(s, '_', UpperCase)
+}
+
+// ToKebab returns words in kebab-case (lower case words with dashes).
+// Also known as dash-case.
+func ToKebab(s string) string {
+ return convertWithoutInitialisms(s, '-', LowerCase)
+}
+
+// ToGoKebab returns words in kebab-case (lower case words with dashes).
+// Also known as dash-case.
+//
+// Respects Go's common initialisms (e.g. http-response -> HTTP-response).
+func ToGoKebab(s string) string {
+ return convertWithGoInitialisms(s, '-', LowerCase)
+}
+
+// ToKEBAB returns words in KEBAB-CASE (upper case words with dashes).
+// Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE.
+func ToKEBAB(s string) string {
+ return convertWithoutInitialisms(s, '-', UpperCase)
+}
+
+// ToPascal returns words in PascalCase (capitalized words concatenated together).
+// Also known as UpperPascalCase.
+func ToPascal(s string) string {
+ return convertWithoutInitialisms(s, 0, TitleCase)
+}
+
+// ToGoPascal returns words in PascalCase (capitalized words concatenated together).
+// Also known as UpperPascalCase.
+//
+// Respects Go's common initialisms (e.g. HttpResponse -> HTTPResponse).
+func ToGoPascal(s string) string {
+ return convertWithGoInitialisms(s, 0, TitleCase)
+}
+
+// ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case).
+// Also known as lowerCamelCase or mixedCase.
+func ToCamel(s string) string {
+ return convertWithoutInitialisms(s, 0, CamelCase)
+}
+
+// ToGoCamel returns words in camelCase (capitalized words concatenated together, with first word lower case).
+// Also known as lowerCamelCase or mixedCase.
+//
+// Respects Go's common initialisms, but first word remains lowercased which is
+// important for code generator use cases (e.g. toJson -> toJSON, httpResponse
+// -> httpResponse).
+func ToGoCamel(s string) string {
+ return convertWithGoInitialisms(s, 0, CamelCase)
+}
+
+// ToCase returns words in given case and delimiter.
+func ToCase(s string, wordCase WordCase, delimiter rune) string {
+ return convertWithoutInitialisms(s, delimiter, wordCase)
+}
+
+// ToGoCase returns words in given case and delimiter.
+//
+// Respects Go's common initialisms (e.g. httpResponse -> HTTPResponse).
+func ToGoCase(s string, wordCase WordCase, delimiter rune) string {
+ return convertWithGoInitialisms(s, delimiter, wordCase)
+}
diff --git a/vendor/github.com/ettle/strcase/unicode.go b/vendor/github.com/ettle/strcase/unicode.go
new file mode 100644
index 000000000..b75e25a51
--- /dev/null
+++ b/vendor/github.com/ettle/strcase/unicode.go
@@ -0,0 +1,48 @@
+package strcase
+
+import "unicode"
+
+// Unicode functions, optimized for the common case of ascii
+// No performance lost by wrapping since these functions get inlined by the compiler
+
+func isUpper(r rune) bool {
+ return unicode.IsUpper(r)
+}
+
+func isLower(r rune) bool {
+ return unicode.IsLower(r)
+}
+
+func isNumber(r rune) bool {
+ if r >= '0' && r <= '9' {
+ return true
+ }
+ return unicode.IsNumber(r)
+}
+
+func isSpace(r rune) bool {
+ if r == ' ' || r == '\t' || r == '\n' || r == '\r' {
+ return true
+ } else if r < 128 {
+ return false
+ }
+ return unicode.IsSpace(r)
+}
+
+func toUpper(r rune) rune {
+ if r >= 'a' && r <= 'z' {
+ return r - 32
+ } else if r < 128 {
+ return r
+ }
+ return unicode.ToUpper(r)
+}
+
+func toLower(r rune) rune {
+ if r >= 'A' && r <= 'Z' {
+ return r + 32
+ } else if r < 128 {
+ return r
+ }
+ return unicode.ToLower(r)
+}