caps is a unicode aware, case conversion library for Go.
The following case conversions are available:
go get github.com/chanced/caps
package main
import (
"fmt"
"github.com/chanced/caps"
)
func main() {
fmt.Println(caps.ToCamel("http request"))
// Output:
// HTTPRequest
fmt.Println(caps.ToLowerCamel("some_id"))
// Output:
// someID
fmt.Println(caps.ToLowerCamel("SomeID", caps.WithReplaceStyleCamel()))
// Output:
// someId
// Alternatively:
capsJS := caps.New(caps.Config{
AllowedSymbols: "$",
ReplaceStyle: caps.ReplaceStyleCamel,
})
fmt.Println(capsJS.ToCamel("SomeID"))
// Output:
// someId
}
Word boundaries are determined by the caps.Converter. The provided implementation, caps.StdConverter,
delegates the boundary detection to caps.Tokenizer. The provided implementation, caps.StdTokenizer,
uses the following rules:
" _.!?:;$-(){}[]#@&+~" unless present in AllowedSymbolsWithNumberRules)AllowedSymbols they are
considered breaks even for numbers"ThisVar" would be tokenized into ["This", "Var"])"SomeID" would be tokenized into ["Some", "I", "D"]).caps.StdConverter also allows users to register caps.Replacements for
initialism replacements. Each Replacement is indexed in a trie (see
Index).
"ID", "UTF8").["U", "U", "I", "D"]) are
evaluated as a potential Replacement until a non-match is
found or the sequence is broken by a token string with more than one rune.{"Acl", "ACL"}
{"Api", "API"}
{"Ascii", "ASCII"}
{"Cpu", "CPU"}
{"Css", "CSS"}
{"Dns", "DNS"}
{"Eof", "EOF"}
{"Guid", "GUID"}
{"Html", "HTML"}
{"Http", "HTTP"}
{"Https", "HTTPS"}
{"Id", "ID"}
{"Ip", "IP"}
{"Json", "JSON"}
{"Lhs", "LHS"}
{"Qps", "QPS"}
{"Ram", "RAM"}
{"Rhs", "RHS"}
{"Rpc", "RPC"}
{"Sla", "SLA"}
{"Smtp", "SMTP"}
{"Sql", "SQL"}
{"Ssh", "SSH"}
{"Tcp", "TCP"}
{"Tls", "TLS"}
{"Ttl", "TTL"}
{"Udp", "UDP"}
{"Ui", "UI"}
{"Uid", "UID"}
{"Uuid", "UUID"}
{"Uri", "URI"}
{"Url", "URL"}
{"Utf8", "UTF8"}
{"Vm", "VM"}
{"Xml", "XML"}
{"Xmpp", "XMPP"}
{"Xsrf", "XSRF"}
{"Xss", "XSS"}
If you would like to add or remove entries from that list, you have a few options. See below.
ConverterThis is likely your best option. You can create and utilize an instance of
caps.Caps which has all of the conversions as methods:
package main
import (
"fmt"
"github.com/chanced/caps"
)
func main() {
c := caps.New(caps.Config{
Replacements: []caps.Replacement{
{Camel: "Ex", Screaming: "EX"},
// ... your replacements
},
})
fmt.Println(c.ToCamel("some ex"))
// Output:
// SomeEX
}
caps.StdConverter instancesYou can pass a new instance of caps.StdConverter with a new set of
caps.Replacement.
package main
import (
"fmt"
"github.com/chanced/caps"
"github.com/chanced/caps/token"
)
func main() {
replacements := []caps.Replacement{
{"Ex", "EX" },
// ... your replacements
}
converter := caps.NewConverter(replacements, caps.DefaultTokenizer, token.DefaultCaser)
fmt.Println(caps.ToCamel("ex id", caps.WithConverter(converter)))
// note: ID was not in the replacement list above
// Output:
// "EXId"
fmt.Println(caps.ToCamel("ex id"))
// Output:
// ExID
}
caps.DefaultConverter globalYou can update caps.DefaultConverter. You should set it before you make any
conversions. Otherwise, you'll need guard your usage of the library accordingly
(e.g. a mutex).
package main
import (
"fmt"
"github.com/chanced/caps"
)
func main() {
converter, _ := caps.DefaultConverter.(caps.StdConverter)
converter.Set("Gcp", "GCP")
fmt.Println(caps.ToCamel("some_gcp_var"))
// Output:
// SomeGCPVar
}
caps.ConverterFinally, if you are so inclined, you can create your own caps.Converter. This
could be as simple as implementing the single Convert method, calling
caps.DefaultConverter.Convert, and then modifying the result.
package main
import (
"fmt"
"github.com/chanced/caps"
)
type MyConverter struct{}
func (MyConverter) Convert(req caps.ConvertRequest) string {
res := caps.DefaultConverter.Convert(req)
if req.Style.IsLowerCamel() && req.ReplaceStyle.IsCamel() && res == "id" {
return "_id"
}
return res
}
func main() {
fmt.Println(caps.ToLowerCamel("ID", caps.WithReplaceStyleCamel(), caps.WithConverter(MyConverter{})))
// Output:
// _id
}
caps supports Turkish and Azeri through the token.Caser interface. It is
satisfied by unicode.TurkishCase and unicode.AzeriCase. token.TurkishCaser
and token.AzeriCaser are available as pointers to those variables (although
you can use the unicode variables directly).
For example, to use Turkish, you would need to instantiate a few variables:
package main
import (
"github.com/chanced/caps"
"github.com/chanced/caps/token"
)
func main() {
tokenizer := caps.NewTokenizer(caps.DEFAULT_DELIMITERS, token.TurkishCaser)
// I suppose these would need to be specific to Turkish?
// if not, you can just use caps.DefaultReplacements
replacements := []caps.Replacement{
{ Camel: "Http", Screaming: "HTTP" }, // just an example
}
turkish := caps.NewConverter(replacements, tokenizer, token.TurkishCaser)
// to use this as your default throughout your application
// you can overwrite caps.DefaultConverter
//
// caps.DefaultConverter = turkish
//
// otherwise, you can pass in the converter to the config for each call:
fmt.Println(caps.ToScreamingKebab("i ı", caps.WithConverter(turkish)))
// Output:
// İ-I
}
The text package contains two types:
Text which has all of the case conversions and relevant functions from strings as methods.Texts which is a sortable slice of Text with a few helper methodspackage main
import (
"fmt"
"github.com/chanced/caps/text"
)
func main() {
t := text.Text("Hello World")
for _, p := range t.ToKebab().Split("-") {
fmt.Println(p)
}
// Output:
// hello
// world
}
input: "Example Uuid."
goos: darwin
goarch: arm64
pkg: github.com/chanced/caps
Using a caps.Caps instance:
BenchmarkCapsToTitle
BenchmarkCapsToTitle-10 2488982 470.2 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToCamel
BenchmarkCapsToCamel-10 2474846 467.8 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToLowerCamel
BenchmarkCapsToLowerCamel-10 2650843 451.0 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToSnake
BenchmarkCapsToSnake-10 2619945 456.9 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToScreamingSnake
BenchmarkCapsToScreamingSnake-10 2591302 461.9 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToKebab
BenchmarkCapsToKebab-10 2621020 457.0 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToScreamingKebab
BenchmarkCapsToScreamingKebab-10 2593428 466.3 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToDotNotation
BenchmarkCapsToDotNotation-10 2575178 463.0 ns/op 200 B/op 8 allocs/op
BenchmarkCapsToScreamingDotNotation
BenchmarkCapsToScreamingDotNotation-10 2526782 472.8 ns/op 200 B/op 8 allocs/op
Using top-level functions:
BenchmarkToTitle
BenchmarkToTitle-10 2316468 519.1 ns/op 200 B/op 8 allocs/op
BenchmarkToCamel
BenchmarkToCamel-10 2327542 516.8 ns/op 200 B/op 8 allocs/op
BenchmarkToLowerCamel
BenchmarkToLowerCamel-10 2372518 505.3 ns/op 200 B/op 8 allocs/op
BenchmarkToSnake
BenchmarkToSnake-10 2337992 511.8 ns/op 200 B/op 8 allocs/op
BenchmarkToScreamingSnake
BenchmarkToScreamingSnake-10 2313232 518.8 ns/op 200 B/op 8 allocs/op
BenchmarkToKebab
BenchmarkToKebab-10 2333046 513.7 ns/op 200 B/op 8 allocs/op
BenchmarkToScreamingKebab
BenchmarkToScreamingKebab-10 2274729 521.3 ns/op 200 B/op 8 allocs/op
BenchmarkToDotNotation
BenchmarkToDotNotation-10 2319278 511.0 ns/op 200 B/op 8 allocs/op
BenchmarkToScreamingDotNotation
BenchmarkToScreamingDotNotation-10 2310217 518.5 ns/op 200 B/op 8 allocs/op
MIT