pax_global_header00006660000000000000000000000064136255444300014520gustar00rootroot0000000000000052 comment=7962b205553802087345c0b4c74d57b65236f676 go-strcase-1.2.0/000077500000000000000000000000001362554443000135675ustar00rootroot00000000000000go-strcase-1.2.0/.circleci/000077500000000000000000000000001362554443000154225ustar00rootroot00000000000000go-strcase-1.2.0/.circleci/config.yml000066400000000000000000000015721362554443000174170ustar00rootroot00000000000000version: 2.1 orbs: codecov: codecov/codecov@1.0.5 jobs: build: docker: - image: golang:1.13 working_directory: /work steps: - checkout - run: name: Install golangci-lint environment: GOLANGCI_LINT_VERSION: 1.21.0 command: | wget -q https://github.com/golangci/golangci-lint/releases/download/v$GOLANGCI_LINT_VERSION/golangci-lint-$GOLANGCI_LINT_VERSION-linux-amd64.tar.gz \ -O /tmp/golangci-lint.tar.gz tar --strip-components=1 -C $GOPATH/bin -xzf /tmp/golangci-lint.tar.gz golangci-lint --version - run: name: Code analysis command: golangci-lint run -v --config .golangci.yml ./... - run: name: Test command: go test -mod=readonly -v -race -count=1 -cover -coverprofile=profile.cov ./... - codecov/upload: file: /work/profile.covgo-strcase-1.2.0/.gitignore000066400000000000000000000002561362554443000155620ustar00rootroot00000000000000# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders vendor doc # Temporary files *~ *.swp # Editor and IDE config .idea *.iml .vscode go-strcase-1.2.0/.golangci.yml000066400000000000000000000004511362554443000161530ustar00rootroot00000000000000run: deadline: 10m linters: enable: - dupl - goconst - gocyclo - godox - gosec - interfacer - lll - maligned - misspell - prealloc - stylecheck - unconvert - unparam - errcheck - golint - gofmt disable: [] fast: false issues: exclude-use-default: false go-strcase-1.2.0/LICENSE000066400000000000000000000021311362554443000145710ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2017, Adrian Stoewer 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. go-strcase-1.2.0/README.md000066400000000000000000000027301362554443000150500ustar00rootroot00000000000000[![CircleCI](https://circleci.com/gh/stoewer/go-strcase/tree/master.svg?style=svg)](https://circleci.com/gh/stoewer/go-strcase/tree/master) [![codecov](https://codecov.io/gh/stoewer/go-strcase/branch/master/graph/badge.svg)](https://codecov.io/gh/stoewer/go-strcase) [![GoDoc](https://godoc.org/github.com/stoewer/go-strcase?status.svg)](https://pkg.go.dev/github.com/stoewer/go-strcase) --- Go strcase ========== The package `strcase` converts between different kinds of naming formats such as camel case (`CamelCase`), snake case (`snake_case`) or kebab case (`kebab-case`). The package is designed to work only with strings consisting of standard ASCII letters. Unicode is currently not supported. Versioning and stability ------------------------ Although the master branch is supposed to remain always backward compatible, the repository contains version tags in order to support vendoring tools. The tag names follow semantic versioning conventions and have the following format `v1.0.0`. This package supports Go modules introduced with version 1.11. Example ------- ```go import "github.com/stoewer/go-strcase" var snake = strcase.SnakeCase("CamelCase") ``` Dependencies ------------ ### Build dependencies * none ### Test dependencies * `github.com/stretchr/testify` Run linters and unit tests -------------------------- To run the static code analysis, linters and tests use the following commands: ``` golangci-lint run --config .golangci.yml ./... go test ./... ``` go-strcase-1.2.0/camel.go000066400000000000000000000015501362554443000152000ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase import ( "strings" ) // UpperCamelCase converts a string into camel case starting with a upper case letter. func UpperCamelCase(s string) string { return camelCase(s, true) } // LowerCamelCase converts a string into camel case starting with a lower case letter. func LowerCamelCase(s string) string { return camelCase(s, false) } func camelCase(s string, upper bool) string { s = strings.TrimSpace(s) buffer := make([]rune, 0, len(s)) stringIter(s, func(prev, curr, next rune) { if !isDelimiter(curr) { if isDelimiter(prev) || (upper && prev == 0) { buffer = append(buffer, toUpper(curr)) } else if isLower(prev) { buffer = append(buffer, curr) } else { buffer = append(buffer, toLower(curr)) } } }) return string(buffer) } go-strcase-1.2.0/camel_test.go000066400000000000000000000027761362554443000162520ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase import ( "testing" "github.com/stretchr/testify/assert" ) func TestUpperCamelCase(t *testing.T) { data := map[string]string{ "": "", "f": "F", "foo": "Foo", "fooBar": "FooBar", "FooBarBla": "FooBarBla", "foo_barBla": "FooBarBla", " foo_bar\n": "FooBar", " foo-bar\t": "FooBar", " foo bar\r": "FooBar", "HTTP_status_code": "HttpStatusCode", "skip many spaces": "SkipManySpaces", "skip---many-dashes": "SkipManyDashes", "skip___many_underline": "SkipManyUnderline", } for in, out := range data { converted := UpperCamelCase(in) assert.Equal(t, out, converted) } } func TestLowerCamelCase(t *testing.T) { data := map[string]string{ "": "", "F": "f", "foo": "foo", "FooBar": "fooBar", "fooBarBla": "fooBarBla", "foo_barBla": "fooBarBla", " foo_bar\n": "fooBar", " foo-bar\t": "fooBar", " foo bar\r": "fooBar", "HTTP_status_code": "httpStatusCode", "skip many spaces": "skipManySpaces", "skip---many-dashes": "skipManyDashes", "skip___many_underline": "skipManyUnderline", } for in, out := range data { converted := LowerCamelCase(in) assert.Equal(t, out, converted) } } go-strcase-1.2.0/doc.go000066400000000000000000000006111362554443000146610ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. // Package strcase converts between different kinds of naming formats such as camel case // (CamelCase), snake case (snake_case) or kebab case (kebab-case). The package is designed // to work only with strings consisting of standard ASCII letters. Unicode is currently not // supported. package strcase go-strcase-1.2.0/go.mod000066400000000000000000000001321362554443000146710ustar00rootroot00000000000000module github.com/stoewer/go-strcase go 1.11 require github.com/stretchr/testify v1.5.1 go-strcase-1.2.0/go.sum000066400000000000000000000017101362554443000147210ustar00rootroot00000000000000github.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= go-strcase-1.2.0/helper.go000066400000000000000000000037201362554443000153770ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase // isLower checks if a character is lower case. More precisely it evaluates if it is // in the range of ASCII character 'a' to 'z'. func isLower(ch rune) bool { return ch >= 'a' && ch <= 'z' } // toLower converts a character in the range of ASCII characters 'A' to 'Z' to its lower // case counterpart. Other characters remain the same. func toLower(ch rune) rune { if ch >= 'A' && ch <= 'Z' { return ch + 32 } return ch } // isLower checks if a character is upper case. More precisely it evaluates if it is // in the range of ASCII characters 'A' to 'Z'. func isUpper(ch rune) bool { return ch >= 'A' && ch <= 'Z' } // toLower converts a character in the range of ASCII characters 'a' to 'z' to its lower // case counterpart. Other characters remain the same. func toUpper(ch rune) rune { if ch >= 'a' && ch <= 'z' { return ch - 32 } return ch } // isSpace checks if a character is some kind of whitespace. func isSpace(ch rune) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' } // isDelimiter checks if a character is some kind of whitespace or '_' or '-'. func isDelimiter(ch rune) bool { return ch == '-' || ch == '_' || isSpace(ch) } // iterFunc is a callback that is called fro a specific position in a string. Its arguments are the // rune at the respective string position as well as the previous and the next rune. If curr is at the // first position of the string prev is zero. If curr is at the end of the string next is zero. type iterFunc func(prev, curr, next rune) // stringIter iterates over a string, invoking the callback for every single rune in the string. func stringIter(s string, callback iterFunc) { var prev rune var curr rune for _, next := range s { if curr == 0 { prev = curr curr = next continue } callback(prev, curr, next) prev = curr curr = next } if len(s) > 0 { callback(prev, curr, 0) } } go-strcase-1.2.0/kebab.go000066400000000000000000000005741362554443000151700ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase // KebabCase converts a string into kebab case. func KebabCase(s string) string { return delimiterCase(s, '-', false) } // UpperKebabCase converts a string into kebab case with capital letters. func UpperKebabCase(s string) string { return delimiterCase(s, '-', true) } go-strcase-1.2.0/kebab_test.go000066400000000000000000000033341362554443000162240ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase import ( "testing" "github.com/stretchr/testify/assert" ) func TestKebabCase(t *testing.T) { data := map[string]string{ "": "", "F": "f", "Foo": "foo", "FooB": "foo-b", "FooID": "foo-id", " FooBar\t": "foo-bar", "HTTPStatusCode": "http-status-code", "ParseURL.DoParse": "parse-url.do-parse", "Convert Space": "convert-space", "Convert-dash": "convert-dash", "Skip___MultipleUnderscores": "skip-multiple-underscores", "Skip MultipleSpaces": "skip-multiple-spaces", "Skip---MultipleDashes": "skip-multiple-dashes", } for camel, snake := range data { converted := KebabCase(camel) assert.Equal(t, snake, converted) } } func TestUpperKebabCase(t *testing.T) { data := map[string]string{ "": "", "F": "F", "Foo": "FOO", "FooB": "FOO-B", "FooID": "FOO-ID", " FooBar\t": "FOO-BAR", "HTTPStatusCode": "HTTP-STATUS-CODE", "ParseURL.DoParse": "PARSE-URL.DO-PARSE", "Convert Space": "CONVERT-SPACE", "Convert-dash": "CONVERT-DASH", "Skip___MultipleUnderscores": "SKIP-MULTIPLE-UNDERSCORES", "Skip MultipleSpaces": "SKIP-MULTIPLE-SPACES", "Skip---MultipleDashes": "SKIP-MULTIPLE-DASHES", } for camel, snake := range data { converted := UpperKebabCase(camel) assert.Equal(t, snake, converted) } } go-strcase-1.2.0/snake.go000066400000000000000000000026151362554443000152230ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase import ( "strings" ) // SnakeCase converts a string into snake case. func SnakeCase(s string) string { return delimiterCase(s, '_', false) } // UpperSnakeCase converts a string into snake case with capital letters. func UpperSnakeCase(s string) string { return delimiterCase(s, '_', true) } // delimiterCase converts a string into snake_case or kebab-case depending on the delimiter passed // as second argument. When upperCase is true the result will be UPPER_SNAKE_CASE or UPPER-KEBAB-CASE. func delimiterCase(s string, delimiter rune, upperCase bool) string { s = strings.TrimSpace(s) buffer := make([]rune, 0, len(s)+3) adjustCase := toLower if upperCase { adjustCase = toUpper } var prev rune var curr rune for _, next := range s { if isDelimiter(curr) { if !isDelimiter(prev) { buffer = append(buffer, delimiter) } } else if isUpper(curr) { if isLower(prev) || (isUpper(prev) && isLower(next)) { buffer = append(buffer, delimiter) } buffer = append(buffer, adjustCase(curr)) } else if curr != 0 { buffer = append(buffer, adjustCase(curr)) } prev = curr curr = next } if len(s) > 0 { if isUpper(curr) && isLower(prev) && prev != 0 { buffer = append(buffer, delimiter) } buffer = append(buffer, adjustCase(curr)) } return string(buffer) } go-strcase-1.2.0/snake_test.go000066400000000000000000000033341362554443000162610ustar00rootroot00000000000000// Copyright (c) 2017, A. Stoewer // All rights reserved. package strcase import ( "testing" "github.com/stretchr/testify/assert" ) func TestSnakeCase(t *testing.T) { data := map[string]string{ "": "", "F": "f", "Foo": "foo", "FooB": "foo_b", "FooID": "foo_id", " FooBar\t": "foo_bar", "HTTPStatusCode": "http_status_code", "ParseURL.DoParse": "parse_url.do_parse", "Convert Space": "convert_space", "Convert-dash": "convert_dash", "Skip___MultipleUnderscores": "skip_multiple_underscores", "Skip MultipleSpaces": "skip_multiple_spaces", "Skip---MultipleDashes": "skip_multiple_dashes", } for camel, snake := range data { converted := SnakeCase(camel) assert.Equal(t, snake, converted) } } func TestUpperSnakeCase(t *testing.T) { data := map[string]string{ "": "", "F": "F", "Foo": "FOO", "FooB": "FOO_B", "FooID": "FOO_ID", " FooBar\t": "FOO_BAR", "HTTPStatusCode": "HTTP_STATUS_CODE", "ParseURL.DoParse": "PARSE_URL.DO_PARSE", "Convert Space": "CONVERT_SPACE", "Convert-dash": "CONVERT_DASH", "Skip___MultipleUnderscores": "SKIP_MULTIPLE_UNDERSCORES", "Skip MultipleSpaces": "SKIP_MULTIPLE_SPACES", "Skip---MultipleDashes": "SKIP_MULTIPLE_DASHES", } for camel, snake := range data { converted := UpperSnakeCase(camel) assert.Equal(t, snake, converted) } }