From b2f2446b46bf02821d90ebedadae2bf7ae0e880e Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Mon, 5 Sep 2022 14:27:54 +0200 Subject: 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 --- vendor/github.com/ettle/strcase/.gitignore | 18 + vendor/github.com/ettle/strcase/.golangci.yml | 88 +++++ vendor/github.com/ettle/strcase/.readme.tmpl | 80 ++++ vendor/github.com/ettle/strcase/LICENSE | 21 + vendor/github.com/ettle/strcase/Makefile | 16 + vendor/github.com/ettle/strcase/README.md | 542 ++++++++++++++++++++++++++ vendor/github.com/ettle/strcase/caser.go | 87 +++++ vendor/github.com/ettle/strcase/convert.go | 297 ++++++++++++++ vendor/github.com/ettle/strcase/doc.go | 155 ++++++++ vendor/github.com/ettle/strcase/go.mod | 5 + vendor/github.com/ettle/strcase/go.sum | 11 + vendor/github.com/ettle/strcase/initialism.go | 43 ++ vendor/github.com/ettle/strcase/split.go | 164 ++++++++ vendor/github.com/ettle/strcase/strcase.go | 81 ++++ vendor/github.com/ettle/strcase/unicode.go | 48 +++ 15 files changed, 1656 insertions(+) create mode 100644 vendor/github.com/ettle/strcase/.gitignore create mode 100644 vendor/github.com/ettle/strcase/.golangci.yml create mode 100644 vendor/github.com/ettle/strcase/.readme.tmpl create mode 100644 vendor/github.com/ettle/strcase/LICENSE create mode 100644 vendor/github.com/ettle/strcase/Makefile create mode 100644 vendor/github.com/ettle/strcase/README.md create mode 100644 vendor/github.com/ettle/strcase/caser.go create mode 100644 vendor/github.com/ettle/strcase/convert.go create mode 100644 vendor/github.com/ettle/strcase/doc.go create mode 100644 vendor/github.com/ettle/strcase/go.mod create mode 100644 vendor/github.com/ettle/strcase/go.sum create mode 100644 vendor/github.com/ettle/strcase/initialism.go create mode 100644 vendor/github.com/ettle/strcase/split.go create mode 100644 vendor/github.com/ettle/strcase/strcase.go create mode 100644 vendor/github.com/ettle/strcase/unicode.go (limited to 'vendor/github.com/ettle/strcase') 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}}"` + +## Overview +{{comment_md .Doc}} +{{example_html $ ""}} + +## Index{{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}} +#### Examples{{- range $.Examples}} +* [{{example_name .Name}}](#example_{{.Name}}){{- end}}{{- end}} + +{{with .Consts}}## Constants +{{range .}}{{node $ .Decl | pre}} +{{comment_md .Doc}}{{end}}{{end}} +{{with .Vars}}## Variables +{{range .}}{{node $ .Decl | pre}} +{{comment_md .Doc}}{{end}}{{end}} + +{{range .Funcs}}{{$name_html := html .Name}}## func [{{$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}}## type [{{$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}}### func [{{$name_html}}]({{gh_url $ .Decl}}) +{{node $ .Decl | pre}} +{{comment_md .Doc}} +{{example_html $ .Name}}{{end}} +{{callgraph_html $ "" .Name}} + +{{range .Methods}}{{$name_html := html .Name}}### func ({{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 := .}} +## {{noteTitle $marker | html}}s + +{{end}} +{{end}} +{{if .Dirs}} +## Subdirectories +{{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"` + +## Overview +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 (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) + + + + +## Index +* [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) + + + + + +## func [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. + + + +## func [ToCase](./strcase.go#L70) +``` go +func ToCase(s string, wordCase WordCase, delimiter rune) string +``` +ToCase returns words in given case and delimiter. + + + +## func [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). + + + +## func [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). + + + +## func [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). + + + +## func [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). + + + +## func [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). + + + +## func [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. + + + +## func [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. + + + +## func [ToPascal](./strcase.go#L43) +``` go +func ToPascal(s string) string +``` +ToPascal returns words in PascalCase (capitalized words concatenated together). +Also known as UpperPascalCase. + + + +## func [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. + + + +## func [ToSnake](./strcase.go#L4) +``` go +func ToSnake(s string) string +``` +ToSnake returns words in snake_case (lower case words with underscores). + + + + +## type [Caser](./caser.go#L4-L7) +``` go +type Caser struct { + // contains filtered or unexported fields +} + +``` +Caser allows for customization of parsing and intialisms + + + + + + + +### func [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. + + + + + +### func (\*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. + + + + +### func (\*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. + + + + +### func (\*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. + + + + +### func (\*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. + + + + +### func (\*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. + + + + +### func (\*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. + + + + +### func (\*Caser) [ToSnake](./caser.go#L50) +``` go +func (c *Caser) ToSnake(s string) string +``` +ToSnake returns words in snake_case (lower case words with underscores). + + + + +## type [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 +) +``` + + + + + + + + + +## type [SplitFn](./split.go#L6) +``` go +type SplitFn func(prev, curr, next rune) SplitAction +``` +SplitFn defines how to split a string into words + + + + + + + +### func [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 + + + + + +## type [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 +) +``` + + + + + + + + + +## type [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) +} -- cgit mrf-deployment