mirror of
https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent.git
synced 2026-07-03 19:51:40 +02:00
Initial v1.0.0 commit
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
*.log
|
||||
.DS_Store
|
||||
doc
|
||||
tmp
|
||||
pkg
|
||||
*.gem
|
||||
*.pid
|
||||
coverage
|
||||
coverage.data
|
||||
build/*
|
||||
*.pbxuser
|
||||
*.mode1v3
|
||||
.svn
|
||||
profile
|
||||
.console_history
|
||||
.sass-cache/*
|
||||
.rake_tasks~
|
||||
*.log.lck
|
||||
solr/
|
||||
.jhw-cache/
|
||||
jhw.*
|
||||
*.sublime*
|
||||
node_modules/
|
||||
dist/
|
||||
generated/
|
||||
.vendor/
|
||||
bin/*
|
||||
gin-bin
|
||||
.idea/
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"]
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Mark Bates
|
||||
|
||||
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.
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
TAGS ?= ""
|
||||
GO_BIN ?= "go"
|
||||
|
||||
install:
|
||||
$(GO_BIN) install -tags ${TAGS} -v .
|
||||
make tidy
|
||||
|
||||
tidy:
|
||||
ifeq ($(GO111MODULE),on)
|
||||
$(GO_BIN) mod tidy
|
||||
else
|
||||
echo skipping go mod tidy
|
||||
endif
|
||||
|
||||
deps:
|
||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||
make tidy
|
||||
|
||||
build:
|
||||
$(GO_BIN) build -v .
|
||||
make tidy
|
||||
|
||||
test:
|
||||
$(GO_BIN) test -cover -tags ${TAGS} ./...
|
||||
make tidy
|
||||
|
||||
ci-deps:
|
||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||
|
||||
ci-test:
|
||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||
|
||||
lint:
|
||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
golangci-lint run --enable-all
|
||||
make tidy
|
||||
|
||||
update:
|
||||
ifeq ($(GO111MODULE),on)
|
||||
rm go.*
|
||||
$(GO_BIN) mod init
|
||||
$(GO_BIN) mod tidy
|
||||
else
|
||||
$(GO_BIN) get -u -tags ${TAGS}
|
||||
endif
|
||||
make test
|
||||
make install
|
||||
make tidy
|
||||
|
||||
release-test:
|
||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||
make tidy
|
||||
|
||||
release:
|
||||
$(GO_BIN) get github.com/gobuffalo/release
|
||||
make tidy
|
||||
release -y -f version.go --skip-packr
|
||||
make tidy
|
||||
|
||||
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# Flect
|
||||
|
||||
<p align="center">
|
||||
<a href="https://godoc.org/github.com/gobuffalo/flect"><img src="https://godoc.org/github.com/gobuffalo/flect?status.svg" alt="GoDoc" /></a>
|
||||
<a href="https://dev.azure.com/markbates/buffalo/_build/latest?definitionId=51&branchName=master"><img src="https://dev.azure.com/markbates/buffalo/_apis/build/status/gobuffalo.flect?branchName=master" alt="CI" /></a>
|
||||
<a href="https://goreportcard.com/report/github.com/gobuffalo/flect"><img src="https://goreportcard.com/badge/github.com/gobuffalo/flect" alt="Go Report Card" /></a>
|
||||
</p>
|
||||
|
||||
This is a new inflection engine to replace [https://github.com/markbates/inflect](https://github.com/markbates/inflect) designed to be more modular, more readable, and easier to fix issues on than the original.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ go get -u -v github.com/gobuffalo/flect
|
||||
```
|
||||
|
||||
## `github.com/gobuffalo/flect`
|
||||
<a href="https://godoc.org/github.com/gobuffalo/flect"><img src="https://godoc.org/github.com/gobuffalo/flect?status.svg" alt="GoDoc" /></a>
|
||||
|
||||
The `github.com/gobuffalo/flect` package contains "basic" inflection tools, like pluralization, singularization, etc...
|
||||
|
||||
### The `Ident` Type
|
||||
|
||||
In addition to helpful methods that take in a `string` and return a `string`, there is an `Ident` type that can be used to create new, custom, inflection rules.
|
||||
|
||||
The `Ident` type contains two fields.
|
||||
|
||||
* `Original` - This is the original `string` that was used to create the `Ident`
|
||||
* `Parts` - This is a `[]string` that represents all of the "parts" of the string, that have been split apart, making the segments easier to work with
|
||||
|
||||
Examples of creating new inflection rules using `Ident` can be found in the `github.com/gobuffalo/flect/name` package.
|
||||
|
||||
## `github.com/gobuffalo/flect/name`
|
||||
<a href="https://godoc.org/github.com/gobuffalo/flect/name"><img src="https://godoc.org/github.com/gobuffalo/flect/name?status.svg" alt="GoDoc" /></a>
|
||||
|
||||
The `github.com/gobuffalo/flect/name` package contains more "business" inflection rules like creating proper names, table names, etc...
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# github.com/gobuffalo/flect Stands on the Shoulders of Giants
|
||||
|
||||
github.com/gobuffalo/flect does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
||||
|
||||
Thank you to the following **GIANTS**:
|
||||
|
||||
|
||||
* [github.com/davecgh/go-spew](https://godoc.org/github.com/davecgh/go-spew)
|
||||
|
||||
* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify)
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package flect
|
||||
|
||||
import "sync"
|
||||
|
||||
var acronymsMoot = &sync.RWMutex{}
|
||||
|
||||
var baseAcronyms = map[string]bool{
|
||||
"OK": true,
|
||||
"UTF8": true,
|
||||
"HTML": true,
|
||||
"JSON": true,
|
||||
"JWT": true,
|
||||
"ID": true,
|
||||
"UUID": true,
|
||||
"SQL": true,
|
||||
"ACK": true,
|
||||
"ACL": true,
|
||||
"ADSL": true,
|
||||
"AES": true,
|
||||
"ANSI": true,
|
||||
"API": true,
|
||||
"ARP": true,
|
||||
"ATM": true,
|
||||
"BGP": true,
|
||||
"BSS": true,
|
||||
"CCITT": true,
|
||||
"CHAP": true,
|
||||
"CIDR": true,
|
||||
"CIR": true,
|
||||
"CLI": true,
|
||||
"CPE": true,
|
||||
"CPU": true,
|
||||
"CRC": true,
|
||||
"CRT": true,
|
||||
"CSMA": true,
|
||||
"CMOS": true,
|
||||
"DCE": true,
|
||||
"DEC": true,
|
||||
"DES": true,
|
||||
"DHCP": true,
|
||||
"DNS": true,
|
||||
"DRAM": true,
|
||||
"DSL": true,
|
||||
"DSLAM": true,
|
||||
"DTE": true,
|
||||
"DMI": true,
|
||||
"EHA": true,
|
||||
"EIA": true,
|
||||
"EIGRP": true,
|
||||
"EOF": true,
|
||||
"ESS": true,
|
||||
"FCC": true,
|
||||
"FCS": true,
|
||||
"FDDI": true,
|
||||
"FTP": true,
|
||||
"GBIC": true,
|
||||
"gbps": true,
|
||||
"GEPOF": true,
|
||||
"HDLC": true,
|
||||
"HTTP": true,
|
||||
"HTTPS": true,
|
||||
"IANA": true,
|
||||
"ICMP": true,
|
||||
"IDF": true,
|
||||
"IDS": true,
|
||||
"IEEE": true,
|
||||
"IETF": true,
|
||||
"IMAP": true,
|
||||
"IP": true,
|
||||
"IPS": true,
|
||||
"ISDN": true,
|
||||
"ISP": true,
|
||||
"kbps": true,
|
||||
"LACP": true,
|
||||
"LAN": true,
|
||||
"LAPB": true,
|
||||
"LAPF": true,
|
||||
"LLC": true,
|
||||
"MAC": true,
|
||||
"Mbps": true,
|
||||
"MC": true,
|
||||
"MDF": true,
|
||||
"MIB": true,
|
||||
"MoCA": true,
|
||||
"MPLS": true,
|
||||
"MTU": true,
|
||||
"NAC": true,
|
||||
"NAT": true,
|
||||
"NBMA": true,
|
||||
"NIC": true,
|
||||
"NRZ": true,
|
||||
"NRZI": true,
|
||||
"NVRAM": true,
|
||||
"OSI": true,
|
||||
"OSPF": true,
|
||||
"OUI": true,
|
||||
"PAP": true,
|
||||
"PAT": true,
|
||||
"PC": true,
|
||||
"PIM": true,
|
||||
"PCM": true,
|
||||
"PDU": true,
|
||||
"POP3": true,
|
||||
"POTS": true,
|
||||
"PPP": true,
|
||||
"PPTP": true,
|
||||
"PTT": true,
|
||||
"PVST": true,
|
||||
"RAM": true,
|
||||
"RARP": true,
|
||||
"RFC": true,
|
||||
"RIP": true,
|
||||
"RLL": true,
|
||||
"ROM": true,
|
||||
"RSTP": true,
|
||||
"RTP": true,
|
||||
"RCP": true,
|
||||
"SDLC": true,
|
||||
"SFD": true,
|
||||
"SFP": true,
|
||||
"SLARP": true,
|
||||
"SLIP": true,
|
||||
"SMTP": true,
|
||||
"SNA": true,
|
||||
"SNAP": true,
|
||||
"SNMP": true,
|
||||
"SOF": true,
|
||||
"SRAM": true,
|
||||
"SSH": true,
|
||||
"SSID": true,
|
||||
"STP": true,
|
||||
"SYN": true,
|
||||
"TDM": true,
|
||||
"TFTP": true,
|
||||
"TIA": true,
|
||||
"TOFU": true,
|
||||
"UDP": true,
|
||||
"URL": true,
|
||||
"URI": true,
|
||||
"USB": true,
|
||||
"UTP": true,
|
||||
"VC": true,
|
||||
"VLAN": true,
|
||||
"VLSM": true,
|
||||
"VPN": true,
|
||||
"W3C": true,
|
||||
"WAN": true,
|
||||
"WEP": true,
|
||||
"WiFi": true,
|
||||
"WPA": true,
|
||||
"WWW": true,
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
variables:
|
||||
GOBIN: "$(GOPATH)/bin" # Go binaries path
|
||||
GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path
|
||||
modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code
|
||||
|
||||
jobs:
|
||||
- job: Windows
|
||||
pool:
|
||||
vmImage: "vs2017-win2016"
|
||||
strategy:
|
||||
matrix:
|
||||
go 1.10:
|
||||
go_version: "1.10"
|
||||
go 1.11 (on):
|
||||
go_version: "1.11.5"
|
||||
GO111MODULE: "on"
|
||||
go 1.11 (off):
|
||||
go_version: "1.11.5"
|
||||
GO111MODULE: "off"
|
||||
go 1.12 (on):
|
||||
go_version: "1.12"
|
||||
GO111MODULE: "on"
|
||||
go 1.12 (off):
|
||||
go_version: "1.12"
|
||||
GO111MODULE: "off"
|
||||
steps:
|
||||
- template: azure-tests.yml
|
||||
|
||||
- job: macOS
|
||||
pool:
|
||||
vmImage: "macOS-10.13"
|
||||
strategy:
|
||||
matrix:
|
||||
go 1.10:
|
||||
go_version: "1.10"
|
||||
go 1.11 (on):
|
||||
go_version: "1.11.5"
|
||||
GO111MODULE: "on"
|
||||
go 1.11 (off):
|
||||
go_version: "1.11.5"
|
||||
GO111MODULE: "off"
|
||||
go 1.12 (on):
|
||||
go_version: "1.12"
|
||||
GO111MODULE: "on"
|
||||
go 1.12 (off):
|
||||
go_version: "1.12"
|
||||
GO111MODULE: "off"
|
||||
steps:
|
||||
- template: azure-tests.yml
|
||||
|
||||
- job: Linux
|
||||
pool:
|
||||
vmImage: "ubuntu-16.04"
|
||||
strategy:
|
||||
matrix:
|
||||
go 1.10:
|
||||
go_version: "1.10"
|
||||
go 1.11 (on):
|
||||
go_version: "1.11.5"
|
||||
GO111MODULE: "on"
|
||||
go 1.11 (off):
|
||||
go_version: "1.11.5"
|
||||
GO111MODULE: "off"
|
||||
go 1.12 (on):
|
||||
go_version: "1.12"
|
||||
GO111MODULE: "on"
|
||||
go 1.12 (off):
|
||||
go_version: "1.12"
|
||||
GO111MODULE: "off"
|
||||
steps:
|
||||
- template: azure-tests.yml
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
inputs:
|
||||
version: $(go_version)
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
mkdir -p "$(GOBIN)"
|
||||
mkdir -p "$(GOPATH)/pkg"
|
||||
mkdir -p "$(modulePath)"
|
||||
shopt -s extglob
|
||||
mv !(gopath) "$(modulePath)"
|
||||
displayName: "Setup Go Workspace"
|
||||
- script: |
|
||||
go get -t -v ./...
|
||||
go test -race ./...
|
||||
workingDirectory: "$(modulePath)"
|
||||
displayName: "Tests"
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Camelize returns a camelize version of a string
|
||||
// bob dylan = bobDylan
|
||||
// widget_id = widgetID
|
||||
// WidgetID = widgetID
|
||||
func Camelize(s string) string {
|
||||
return New(s).Camelize().String()
|
||||
}
|
||||
|
||||
// Camelize returns a camelize version of a string
|
||||
// bob dylan = bobDylan
|
||||
// widget_id = widgetID
|
||||
// WidgetID = widgetID
|
||||
func (i Ident) Camelize() Ident {
|
||||
var out []string
|
||||
for i, part := range i.Parts {
|
||||
var x string
|
||||
var capped bool
|
||||
if strings.ToLower(part) == "id" {
|
||||
out = append(out, "ID")
|
||||
continue
|
||||
}
|
||||
for _, c := range part {
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) {
|
||||
if i == 0 {
|
||||
x += string(unicode.ToLower(c))
|
||||
continue
|
||||
}
|
||||
if !capped {
|
||||
capped = true
|
||||
x += string(unicode.ToUpper(c))
|
||||
continue
|
||||
}
|
||||
x += string(c)
|
||||
}
|
||||
}
|
||||
if x != "" {
|
||||
out = append(out, x)
|
||||
}
|
||||
}
|
||||
return New(strings.Join(out, ""))
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package flect
|
||||
|
||||
import "unicode"
|
||||
|
||||
// Capitalize will cap the first letter of string
|
||||
// user = User
|
||||
// bob dylan = Bob dylan
|
||||
// widget_id = Widget_id
|
||||
func Capitalize(s string) string {
|
||||
return New(s).Capitalize().String()
|
||||
}
|
||||
|
||||
// Capitalize will cap the first letter of string
|
||||
// user = User
|
||||
// bob dylan = Bob dylan
|
||||
// widget_id = Widget_id
|
||||
func (i Ident) Capitalize() Ident {
|
||||
var x string
|
||||
if len(i.Parts) == 0 {
|
||||
return New("")
|
||||
}
|
||||
x = string(unicode.ToTitle(rune(i.Original[0])))
|
||||
if len(i.Original) > 1 {
|
||||
x += i.Original[1:]
|
||||
}
|
||||
return New(x)
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func init() {
|
||||
loadCustomData("inflections.json", "INFLECT_PATH", "could not read inflection file", LoadInflections)
|
||||
loadCustomData("acronyms.json", "ACRONYMS_PATH", "could not read acronyms file", LoadAcronyms)
|
||||
}
|
||||
|
||||
//CustomDataParser are functions that parse data like acronyms or
|
||||
//plurals in the shape of a io.Reader it receives.
|
||||
type CustomDataParser func(io.Reader) error
|
||||
|
||||
func loadCustomData(defaultFile, env, readErrorMessage string, parser CustomDataParser) {
|
||||
pwd, _ := os.Getwd()
|
||||
path, found := os.LookupEnv(env)
|
||||
if !found {
|
||||
path = filepath.Join(pwd, defaultFile)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
fmt.Printf("%s %s (%s)\n", readErrorMessage, path, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = parser(bytes.NewReader(b)); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
//LoadAcronyms loads rules from io.Reader param
|
||||
func LoadAcronyms(r io.Reader) error {
|
||||
m := []string{}
|
||||
err := json.NewDecoder(r).Decode(&m)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not decode acronyms JSON from reader: %s", err)
|
||||
}
|
||||
|
||||
acronymsMoot.Lock()
|
||||
defer acronymsMoot.Unlock()
|
||||
|
||||
for _, acronym := range m {
|
||||
baseAcronyms[acronym] = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//LoadInflections loads rules from io.Reader param
|
||||
func LoadInflections(r io.Reader) error {
|
||||
m := map[string]string{}
|
||||
|
||||
err := json.NewDecoder(r).Decode(&m)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not decode inflection JSON from reader: %s", err)
|
||||
}
|
||||
|
||||
pluralMoot.Lock()
|
||||
defer pluralMoot.Unlock()
|
||||
singularMoot.Lock()
|
||||
defer singularMoot.Unlock()
|
||||
|
||||
for s, p := range m {
|
||||
singleToPlural[s] = p
|
||||
pluralToSingle[p] = s
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Dasherize returns an alphanumeric, lowercased, dashed string
|
||||
// Donald E. Knuth = donald-e-knuth
|
||||
// Test with + sign = test-with-sign
|
||||
// admin/WidgetID = admin-widget-id
|
||||
func Dasherize(s string) string {
|
||||
return New(s).Dasherize().String()
|
||||
}
|
||||
|
||||
// Dasherize returns an alphanumeric, lowercased, dashed string
|
||||
// Donald E. Knuth = donald-e-knuth
|
||||
// Test with + sign = test-with-sign
|
||||
// admin/WidgetID = admin-widget-id
|
||||
func (i Ident) Dasherize() Ident {
|
||||
var parts []string
|
||||
|
||||
for _, part := range i.Parts {
|
||||
var x string
|
||||
for _, c := range part {
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) {
|
||||
x += string(c)
|
||||
}
|
||||
}
|
||||
parts = xappend(parts, x)
|
||||
}
|
||||
|
||||
return New(strings.ToLower(strings.Join(parts, "-")))
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Package flect is a new inflection engine to replace [https://github.com/markbates/inflect](https://github.com/markbates/inflect) designed to be more modular, more readable, and easier to fix issues on than the original.
|
||||
*/
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var spaces = []rune{'_', ' ', ':', '-', '/'}
|
||||
|
||||
func isSpace(c rune) bool {
|
||||
for _, r := range spaces {
|
||||
if r == c {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return unicode.IsSpace(c)
|
||||
}
|
||||
|
||||
func xappend(a []string, ss ...string) []string {
|
||||
for _, s := range ss {
|
||||
s = strings.TrimSpace(s)
|
||||
for _, x := range spaces {
|
||||
s = strings.Trim(s, string(x))
|
||||
}
|
||||
if _, ok := baseAcronyms[strings.ToUpper(s)]; ok {
|
||||
s = strings.ToUpper(s)
|
||||
}
|
||||
if s != "" {
|
||||
a = append(a, s)
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func abs(x int) int {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
module github.com/gobuffalo/flect
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Humanize returns first letter of sentence capitalized.
|
||||
// Common acronyms are capitalized as well.
|
||||
// Other capital letters in string are left as provided.
|
||||
// employee_salary = Employee salary
|
||||
// employee_id = employee ID
|
||||
// employee_mobile_number = Employee mobile number
|
||||
// first_Name = First Name
|
||||
// firstName = First Name
|
||||
func Humanize(s string) string {
|
||||
return New(s).Humanize().String()
|
||||
}
|
||||
|
||||
// Humanize First letter of sentence capitalized
|
||||
func (i Ident) Humanize() Ident {
|
||||
if len(i.Original) == 0 {
|
||||
return New("")
|
||||
}
|
||||
|
||||
var parts []string
|
||||
for index, part := range i.Parts {
|
||||
if index == 0 {
|
||||
part = strings.Title(i.Parts[0])
|
||||
}
|
||||
|
||||
parts = xappend(parts, part)
|
||||
}
|
||||
|
||||
return New(strings.Join(parts, " "))
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Ident represents the string and it's parts
|
||||
type Ident struct {
|
||||
Original string
|
||||
Parts []string
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer and returns the original string
|
||||
func (i Ident) String() string {
|
||||
return i.Original
|
||||
}
|
||||
|
||||
// New creates a new Ident from the string
|
||||
func New(s string) Ident {
|
||||
i := Ident{
|
||||
Original: s,
|
||||
Parts: toParts(s),
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
func toParts(s string) []string {
|
||||
parts := []string{}
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) == 0 {
|
||||
return parts
|
||||
}
|
||||
if _, ok := baseAcronyms[strings.ToUpper(s)]; ok {
|
||||
return []string{strings.ToUpper(s)}
|
||||
}
|
||||
var prev rune
|
||||
var x string
|
||||
for _, c := range s {
|
||||
cs := string(c)
|
||||
// fmt.Println("### cs ->", cs)
|
||||
// fmt.Println("### unicode.IsControl(c) ->", unicode.IsControl(c))
|
||||
// fmt.Println("### unicode.IsDigit(c) ->", unicode.IsDigit(c))
|
||||
// fmt.Println("### unicode.IsGraphic(c) ->", unicode.IsGraphic(c))
|
||||
// fmt.Println("### unicode.IsLetter(c) ->", unicode.IsLetter(c))
|
||||
// fmt.Println("### unicode.IsLower(c) ->", unicode.IsLower(c))
|
||||
// fmt.Println("### unicode.IsMark(c) ->", unicode.IsMark(c))
|
||||
// fmt.Println("### unicode.IsPrint(c) ->", unicode.IsPrint(c))
|
||||
// fmt.Println("### unicode.IsPunct(c) ->", unicode.IsPunct(c))
|
||||
// fmt.Println("### unicode.IsSpace(c) ->", unicode.IsSpace(c))
|
||||
// fmt.Println("### unicode.IsTitle(c) ->", unicode.IsTitle(c))
|
||||
// fmt.Println("### unicode.IsUpper(c) ->", unicode.IsUpper(c))
|
||||
if !utf8.ValidRune(c) {
|
||||
continue
|
||||
}
|
||||
|
||||
if isSpace(c) {
|
||||
parts = xappend(parts, x)
|
||||
x = cs
|
||||
prev = c
|
||||
continue
|
||||
}
|
||||
|
||||
if unicode.IsUpper(c) && !unicode.IsUpper(prev) {
|
||||
parts = xappend(parts, x)
|
||||
x = cs
|
||||
prev = c
|
||||
continue
|
||||
}
|
||||
if unicode.IsUpper(c) && baseAcronyms[strings.ToUpper(x)] {
|
||||
parts = xappend(parts, x)
|
||||
x = cs
|
||||
prev = c
|
||||
continue
|
||||
}
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) || unicode.IsPunct(c) || c == '`' {
|
||||
prev = c
|
||||
x += cs
|
||||
continue
|
||||
}
|
||||
|
||||
parts = xappend(parts, x)
|
||||
x = ""
|
||||
prev = c
|
||||
}
|
||||
parts = xappend(parts, x)
|
||||
|
||||
return parts
|
||||
}
|
||||
|
||||
var _ encoding.TextUnmarshaler = &Ident{}
|
||||
var _ encoding.TextMarshaler = &Ident{}
|
||||
|
||||
//UnmarshalText unmarshalls byte array into the Ident
|
||||
func (i *Ident) UnmarshalText(data []byte) error {
|
||||
(*i) = New(string(data))
|
||||
return nil
|
||||
}
|
||||
|
||||
//MarshalText marshals Ident into byte array
|
||||
func (i Ident) MarshalText() ([]byte, error) {
|
||||
return []byte(i.Original), nil
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package flect
|
||||
|
||||
import "strings"
|
||||
|
||||
// ToUpper is a convience wrapper for strings.ToUpper
|
||||
func (i Ident) ToUpper() Ident {
|
||||
return New(strings.ToUpper(i.Original))
|
||||
}
|
||||
|
||||
// ToLower is a convience wrapper for strings.ToLower
|
||||
func (i Ident) ToLower() Ident {
|
||||
return New(strings.ToLower(i.Original))
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Ordinalize converts a number to an ordinal version
|
||||
// 42 = 42nd
|
||||
// 45 = 45th
|
||||
// 1 = 1st
|
||||
func Ordinalize(s string) string {
|
||||
return New(s).Ordinalize().String()
|
||||
}
|
||||
|
||||
// Ordinalize converts a number to an ordinal version
|
||||
// 42 = 42nd
|
||||
// 45 = 45th
|
||||
// 1 = 1st
|
||||
func (i Ident) Ordinalize() Ident {
|
||||
number, err := strconv.Atoi(i.Original)
|
||||
if err != nil {
|
||||
return i
|
||||
}
|
||||
var s string
|
||||
switch abs(number) % 100 {
|
||||
case 11, 12, 13:
|
||||
s = fmt.Sprintf("%dth", number)
|
||||
default:
|
||||
switch abs(number) % 10 {
|
||||
case 1:
|
||||
s = fmt.Sprintf("%dst", number)
|
||||
case 2:
|
||||
s = fmt.Sprintf("%dnd", number)
|
||||
case 3:
|
||||
s = fmt.Sprintf("%drd", number)
|
||||
}
|
||||
}
|
||||
if s != "" {
|
||||
return New(s)
|
||||
}
|
||||
return New(fmt.Sprintf("%dth", number))
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Pascalize returns a string with each segment capitalized
|
||||
// user = User
|
||||
// bob dylan = BobDylan
|
||||
// widget_id = WidgetID
|
||||
func Pascalize(s string) string {
|
||||
return New(s).Pascalize().String()
|
||||
}
|
||||
|
||||
// Pascalize returns a string with each segment capitalized
|
||||
// user = User
|
||||
// bob dylan = BobDylan
|
||||
// widget_id = WidgetID
|
||||
func (i Ident) Pascalize() Ident {
|
||||
c := i.Camelize()
|
||||
if len(c.String()) == 0 {
|
||||
return c
|
||||
}
|
||||
return New(string(unicode.ToUpper(rune(c.Original[0]))) + c.Original[1:])
|
||||
}
|
||||
+284
@@ -0,0 +1,284 @@
|
||||
package flect
|
||||
|
||||
var pluralRules = []rule{}
|
||||
|
||||
// AddPlural adds a rule that will replace the given suffix with the replacement suffix.
|
||||
func AddPlural(suffix string, repl string) {
|
||||
pluralMoot.Lock()
|
||||
defer pluralMoot.Unlock()
|
||||
pluralRules = append(pluralRules, rule{
|
||||
suffix: suffix,
|
||||
fn: func(s string) string {
|
||||
s = s[:len(s)-len(suffix)]
|
||||
return s + repl
|
||||
},
|
||||
})
|
||||
|
||||
pluralRules = append(pluralRules, rule{
|
||||
suffix: repl,
|
||||
fn: noop,
|
||||
})
|
||||
}
|
||||
|
||||
var singleToPlural = map[string]string{
|
||||
"aircraft": "aircraft",
|
||||
"alias": "aliases",
|
||||
"alumna": "alumnae",
|
||||
"alumnus": "alumni",
|
||||
"analysis": "analyses",
|
||||
"antenna": "antennas",
|
||||
"antithesis": "antitheses",
|
||||
"apex": "apexes",
|
||||
"appendix": "appendices",
|
||||
"axis": "axes",
|
||||
"bacillus": "bacilli",
|
||||
"bacterium": "bacteria",
|
||||
"basis": "bases",
|
||||
"beau": "beaus",
|
||||
"bison": "bison",
|
||||
"bureau": "bureaus",
|
||||
"bus": "buses",
|
||||
"campus": "campuses",
|
||||
"caucus": "caucuses",
|
||||
"château": "châteaux",
|
||||
"circus": "circuses",
|
||||
"codex": "codices",
|
||||
"concerto": "concertos",
|
||||
"corpus": "corpora",
|
||||
"crisis": "crises",
|
||||
"curriculum": "curriculums",
|
||||
"datum": "data",
|
||||
"dear": "dear",
|
||||
"deer": "deer",
|
||||
"diagnosis": "diagnoses",
|
||||
"die": "dice",
|
||||
"dwarf": "dwarves",
|
||||
"ellipsis": "ellipses",
|
||||
"equipment": "equipment",
|
||||
"erratum": "errata",
|
||||
"faux pas": "faux pas",
|
||||
"fez": "fezzes",
|
||||
"fish": "fish",
|
||||
"focus": "foci",
|
||||
"foo": "foos",
|
||||
"foot": "feet",
|
||||
"formula": "formulas",
|
||||
"fungus": "fungi",
|
||||
"genus": "genera",
|
||||
"goose": "geese",
|
||||
"graffito": "graffiti",
|
||||
"grouse": "grouse",
|
||||
"half": "halves",
|
||||
"halo": "halos",
|
||||
"hoof": "hooves",
|
||||
"human": "humans",
|
||||
"hypothesis": "hypotheses",
|
||||
"index": "indices",
|
||||
"information": "information",
|
||||
"jeans": "jeans",
|
||||
"larva": "larvae",
|
||||
"libretto": "librettos",
|
||||
"loaf": "loaves",
|
||||
"locus": "loci",
|
||||
"louse": "lice",
|
||||
"matrix": "matrices",
|
||||
"minutia": "minutiae",
|
||||
"money": "money",
|
||||
"moose": "moose",
|
||||
"mouse": "mice",
|
||||
"nebula": "nebulae",
|
||||
"news": "news",
|
||||
"nucleus": "nuclei",
|
||||
"oasis": "oases",
|
||||
"octopus": "octopi",
|
||||
"offspring": "offspring",
|
||||
"opus": "opera",
|
||||
"ovum": "ova",
|
||||
"ox": "oxen",
|
||||
"parenthesis": "parentheses",
|
||||
"phenomenon": "phenomena",
|
||||
"photo": "photos",
|
||||
"phylum": "phyla",
|
||||
"piano": "pianos",
|
||||
"plus": "pluses",
|
||||
"police": "police",
|
||||
"prognosis": "prognoses",
|
||||
"prometheus": "prometheuses",
|
||||
"quiz": "quizzes",
|
||||
"radius": "radiuses",
|
||||
"referendum": "referendums",
|
||||
"ress": "resses",
|
||||
"rice": "rice",
|
||||
"salmon": "salmon",
|
||||
"series": "series",
|
||||
"sheep": "sheep",
|
||||
"shoe": "shoes",
|
||||
"shrimp": "shrimp",
|
||||
"species": "species",
|
||||
"stimulus": "stimuli",
|
||||
"stratum": "strata",
|
||||
"swine": "swine",
|
||||
"syllabus": "syllabi",
|
||||
"symposium": "symposiums",
|
||||
"synopsis": "synopses",
|
||||
"tableau": "tableaus",
|
||||
"testis": "testes",
|
||||
"thesis": "theses",
|
||||
"thief": "thieves",
|
||||
"tooth": "teeth",
|
||||
"trout": "trout",
|
||||
"tuna": "tuna",
|
||||
"vertebra": "vertebrae",
|
||||
"vertix": "vertices",
|
||||
"vita": "vitae",
|
||||
"vortex": "vortices",
|
||||
"wharf": "wharves",
|
||||
"wife": "wives",
|
||||
"wolf": "wolves",
|
||||
"you": "you",
|
||||
}
|
||||
|
||||
var pluralToSingle = map[string]string{}
|
||||
|
||||
func init() {
|
||||
for k, v := range singleToPlural {
|
||||
pluralToSingle[v] = k
|
||||
}
|
||||
}
|
||||
|
||||
type singularToPluralSuffix struct {
|
||||
singular string
|
||||
plural string
|
||||
}
|
||||
|
||||
var singularToPluralSuffixList = []singularToPluralSuffix{
|
||||
{"iterion", "iteria"},
|
||||
{"campus", "campuses"},
|
||||
{"genera", "genus"},
|
||||
{"person", "people"},
|
||||
{"phylum", "phyla"},
|
||||
{"randum", "randa"},
|
||||
{"actus", "acti"},
|
||||
{"adium", "adia"},
|
||||
{"alias", "aliases"},
|
||||
{"basis", "basis"},
|
||||
{"child", "children"},
|
||||
{"chive", "chives"},
|
||||
{"focus", "foci"},
|
||||
{"hello", "hellos"},
|
||||
{"jeans", "jeans"},
|
||||
{"louse", "lice"},
|
||||
{"mouse", "mice"},
|
||||
{"movie", "movies"},
|
||||
{"oasis", "oasis"},
|
||||
{"atum", "ata"},
|
||||
{"atus", "atuses"},
|
||||
{"base", "bases"},
|
||||
{"cess", "cesses"},
|
||||
{"dium", "diums"},
|
||||
{"eses", "esis"},
|
||||
{"half", "halves"},
|
||||
{"hive", "hives"},
|
||||
{"iano", "ianos"},
|
||||
{"irus", "iri"},
|
||||
{"isis", "ises"},
|
||||
{"leus", "li"},
|
||||
{"mnus", "mni"},
|
||||
{"move", "moves"},
|
||||
{"news", "news"},
|
||||
{"odex", "odice"},
|
||||
{"oose", "eese"},
|
||||
{"ouse", "ouses"},
|
||||
{"ovum", "ova"},
|
||||
{"rion", "ria"},
|
||||
{"shoe", "shoes"},
|
||||
{"stis", "stes"},
|
||||
{"tive", "tives"},
|
||||
{"wife", "wives"},
|
||||
{"afe", "aves"},
|
||||
{"bfe", "bves"},
|
||||
{"box", "boxes"},
|
||||
{"cfe", "cves"},
|
||||
{"dfe", "dves"},
|
||||
{"dge", "dges"},
|
||||
{"efe", "eves"},
|
||||
{"gfe", "gves"},
|
||||
{"hfe", "hves"},
|
||||
{"ife", "ives"},
|
||||
{"itz", "itzes"},
|
||||
{"ium", "ia"},
|
||||
{"ize", "izes"},
|
||||
{"jfe", "jves"},
|
||||
{"kfe", "kves"},
|
||||
{"man", "men"},
|
||||
{"mfe", "mves"},
|
||||
{"nfe", "nves"},
|
||||
{"nna", "nnas"},
|
||||
{"oaf", "oaves"},
|
||||
{"oci", "ocus"},
|
||||
{"ode", "odes"},
|
||||
{"ofe", "oves"},
|
||||
{"oot", "eet"},
|
||||
{"pfe", "pves"},
|
||||
{"pse", "psis"},
|
||||
{"qfe", "qves"},
|
||||
{"quy", "quies"},
|
||||
{"rfe", "rves"},
|
||||
{"sfe", "sves"},
|
||||
{"tfe", "tves"},
|
||||
{"tum", "ta"},
|
||||
{"tus", "tuses"},
|
||||
{"ufe", "uves"},
|
||||
{"ula", "ulae"},
|
||||
{"ula", "ulas"},
|
||||
{"uli", "ulus"},
|
||||
{"use", "uses"},
|
||||
{"uss", "usses"},
|
||||
{"vfe", "vves"},
|
||||
{"wfe", "wves"},
|
||||
{"xfe", "xves"},
|
||||
{"yfe", "yves"},
|
||||
{"you", "you"},
|
||||
{"zfe", "zves"},
|
||||
{"by", "bies"},
|
||||
{"ch", "ches"},
|
||||
{"cy", "cies"},
|
||||
{"dy", "dies"},
|
||||
{"ex", "ices"},
|
||||
{"fy", "fies"},
|
||||
{"gy", "gies"},
|
||||
{"hy", "hies"},
|
||||
{"io", "ios"},
|
||||
{"jy", "jies"},
|
||||
{"ky", "kies"},
|
||||
{"ld", "ldren"},
|
||||
{"lf", "lves"},
|
||||
{"ly", "lies"},
|
||||
{"my", "mies"},
|
||||
{"ny", "nies"},
|
||||
{"ox", "oxen"},
|
||||
{"py", "pies"},
|
||||
{"qy", "qies"},
|
||||
{"rf", "rves"},
|
||||
{"ry", "ries"},
|
||||
{"sh", "shes"},
|
||||
{"ss", "sses"},
|
||||
{"sy", "sies"},
|
||||
{"ty", "ties"},
|
||||
{"tz", "tzes"},
|
||||
{"va", "vae"},
|
||||
{"vy", "vies"},
|
||||
{"wy", "wies"},
|
||||
{"xy", "xies"},
|
||||
{"zy", "zies"},
|
||||
{"zz", "zzes"},
|
||||
{"o", "oes"},
|
||||
{"x", "xes"},
|
||||
}
|
||||
|
||||
func init() {
|
||||
for _, suffix := range singularToPluralSuffixList {
|
||||
AddPlural(suffix.singular, suffix.plural)
|
||||
AddSingular(suffix.plural, suffix.singular)
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var pluralMoot = &sync.RWMutex{}
|
||||
|
||||
// Pluralize returns a plural version of the string
|
||||
// user = users
|
||||
// person = people
|
||||
// datum = data
|
||||
func Pluralize(s string) string {
|
||||
return New(s).Pluralize().String()
|
||||
}
|
||||
|
||||
// Pluralize returns a plural version of the string
|
||||
// user = users
|
||||
// person = people
|
||||
// datum = data
|
||||
func (i Ident) Pluralize() Ident {
|
||||
s := i.Original
|
||||
if len(s) == 0 {
|
||||
return New("")
|
||||
}
|
||||
|
||||
pluralMoot.RLock()
|
||||
defer pluralMoot.RUnlock()
|
||||
|
||||
ls := strings.ToLower(s)
|
||||
if _, ok := pluralToSingle[ls]; ok {
|
||||
return i
|
||||
}
|
||||
if p, ok := singleToPlural[ls]; ok {
|
||||
return New(p)
|
||||
}
|
||||
for _, r := range pluralRules {
|
||||
if strings.HasSuffix(ls, r.suffix) {
|
||||
return New(r.fn(s))
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasSuffix(ls, "s") {
|
||||
return i
|
||||
}
|
||||
|
||||
return New(i.String() + "s")
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package flect
|
||||
|
||||
type ruleFn func(string) string
|
||||
|
||||
type rule struct {
|
||||
suffix string
|
||||
fn ruleFn
|
||||
}
|
||||
|
||||
func noop(s string) string { return s }
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package flect
|
||||
|
||||
var singularRules = []rule{}
|
||||
|
||||
// AddSingular adds a rule that will replace the given suffix with the replacement suffix.
|
||||
func AddSingular(ext string, repl string) {
|
||||
singularMoot.Lock()
|
||||
defer singularMoot.Unlock()
|
||||
singularRules = append(singularRules, rule{
|
||||
suffix: ext,
|
||||
fn: func(s string) string {
|
||||
s = s[:len(s)-len(ext)]
|
||||
return s + repl
|
||||
},
|
||||
})
|
||||
|
||||
singularRules = append(singularRules, rule{
|
||||
suffix: repl,
|
||||
fn: func(s string) string {
|
||||
return s
|
||||
},
|
||||
})
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var singularMoot = &sync.RWMutex{}
|
||||
|
||||
// Singularize returns a singular version of the string
|
||||
// users = user
|
||||
// data = datum
|
||||
// people = person
|
||||
func Singularize(s string) string {
|
||||
return New(s).Singularize().String()
|
||||
}
|
||||
|
||||
// Singularize returns a singular version of the string
|
||||
// users = user
|
||||
// data = datum
|
||||
// people = person
|
||||
func (i Ident) Singularize() Ident {
|
||||
s := i.Original
|
||||
if len(s) == 0 {
|
||||
return i
|
||||
}
|
||||
|
||||
singularMoot.RLock()
|
||||
defer singularMoot.RUnlock()
|
||||
ls := strings.ToLower(s)
|
||||
if p, ok := pluralToSingle[ls]; ok {
|
||||
return New(p)
|
||||
}
|
||||
if _, ok := singleToPlural[ls]; ok {
|
||||
return i
|
||||
}
|
||||
for _, r := range singularRules {
|
||||
if strings.HasSuffix(ls, r.suffix) {
|
||||
return New(r.fn(s))
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasSuffix(s, "s") {
|
||||
return New(s[:len(s)-1])
|
||||
}
|
||||
return i
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Titleize will capitalize the start of each part
|
||||
// "Nice to see you!" = "Nice To See You!"
|
||||
// "i've read a book! have you?" = "I've Read A Book! Have You?"
|
||||
// "This is `code` ok" = "This Is `code` OK"
|
||||
func Titleize(s string) string {
|
||||
return New(s).Titleize().String()
|
||||
}
|
||||
|
||||
// Titleize will capitalize the start of each part
|
||||
// "Nice to see you!" = "Nice To See You!"
|
||||
// "i've read a book! have you?" = "I've Read A Book! Have You?"
|
||||
// "This is `code` ok" = "This Is `code` OK"
|
||||
func (i Ident) Titleize() Ident {
|
||||
var parts []string
|
||||
for _, part := range i.Parts {
|
||||
x := string(unicode.ToTitle(rune(part[0])))
|
||||
if len(part) > 1 {
|
||||
x += part[1:]
|
||||
}
|
||||
parts = append(parts, x)
|
||||
}
|
||||
return New(strings.Join(parts, " "))
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package flect
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Underscore a string
|
||||
// bob dylan = bob_dylan
|
||||
// Nice to see you! = nice_to_see_you
|
||||
// widgetID = widget_id
|
||||
func Underscore(s string) string {
|
||||
return New(s).Underscore().String()
|
||||
}
|
||||
|
||||
// Underscore a string
|
||||
// bob dylan = bob_dylan
|
||||
// Nice to see you! = nice_to_see_you
|
||||
// widgetID = widget_id
|
||||
func (i Ident) Underscore() Ident {
|
||||
var out []string
|
||||
for _, part := range i.Parts {
|
||||
var x string
|
||||
for _, c := range part {
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) {
|
||||
x += string(c)
|
||||
}
|
||||
}
|
||||
if x != "" {
|
||||
out = append(out, x)
|
||||
}
|
||||
}
|
||||
return New(strings.ToLower(strings.Join(out, "_")))
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package flect
|
||||
|
||||
//Version holds Flect version number
|
||||
const Version = "v0.1.6"
|
||||
Reference in New Issue
Block a user