mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-20 04:22:25 +08:00
Compare commits
14 Commits
e435fa271b
...
v2.1.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7e5d946f1 | ||
|
|
687db4ce79 | ||
|
|
a9a4bb8841 | ||
|
|
bc6cb5f61b | ||
|
|
2c57266f8e | ||
|
|
57e49c9520 | ||
|
|
985c9a5d9a | ||
|
|
5cfb11f036 | ||
|
|
5b3d48a1e7 | ||
|
|
d0576e028f | ||
|
|
76bdec2b54 | ||
|
|
fa20aba3a7 | ||
|
|
7a4a429e23 | ||
|
|
a70ec6ad1e |
10
README.md
10
README.md
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -38,10 +38,10 @@ English | [简体中文](./README_zh-CN.md)
|
||||
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
||||
```
|
||||
|
||||
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.3.4. </b>
|
||||
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.3.5. </b>
|
||||
|
||||
```go
|
||||
go get github.com/duke-git/lancet@v1.3.3 // below go1.18, install latest version of v1.x.x
|
||||
go get github.com/duke-git/lancet@v1.3.5 // below go1.18, install latest version of v1.x.x
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -371,7 +371,6 @@ import "github.com/duke-git/lancet/v2/netutil"
|
||||
- [SendRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#SendRequest)
|
||||
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#DecodeResponse)
|
||||
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#StructToUrlValues)
|
||||
|
||||
- [HttpGet<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)
|
||||
- [HttpDelete<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)
|
||||
- [HttpPost<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)
|
||||
@@ -488,12 +487,14 @@ import "github.com/duke-git/lancet/v2/strutil"
|
||||
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Capitalize)
|
||||
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#IsString)
|
||||
- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#KebabCase)
|
||||
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperKebabCase)
|
||||
- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#LowerFirst)
|
||||
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperFirst)
|
||||
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadEnd)
|
||||
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart)
|
||||
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Reverse)
|
||||
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase)
|
||||
- [UpperSnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperSnakeCase)
|
||||
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SplitEx)
|
||||
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap)
|
||||
@@ -551,6 +552,7 @@ import "github.com/duke-git/lancet/v2/validator"
|
||||
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl)
|
||||
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
|
||||
- [IsZeroValue](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsZeroValue)
|
||||
- [IsGBK](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsGBK)
|
||||
|
||||
### 20. xerror package implements helpers for errors.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -37,10 +37,10 @@
|
||||
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
||||
```
|
||||
|
||||
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.3.4。</b>
|
||||
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.3.5。</b>
|
||||
|
||||
```go
|
||||
go get github.com/duke-git/lancet@v1.3.3 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
||||
go get github.com/duke-git/lancet@v1.3.5 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
||||
```
|
||||
|
||||
## 用法
|
||||
@@ -370,7 +370,6 @@ import "github.com/duke-git/lancet/v2/netutil"
|
||||
- [SendRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#SendRequest)
|
||||
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#DecodeResponse)
|
||||
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#StructToUrlValues)
|
||||
|
||||
- [HttpGet<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)
|
||||
- [HttpDelete<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)
|
||||
- [HttpPost<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)
|
||||
@@ -485,12 +484,14 @@ import "github.com/duke-git/lancet/v2/strutil"
|
||||
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Capitalize)
|
||||
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#IsString)
|
||||
- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#KebabCase)
|
||||
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperKebabCase)
|
||||
- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#LowerFirst)
|
||||
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperFirst)
|
||||
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadEnd)
|
||||
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart)
|
||||
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Reverse)
|
||||
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase)
|
||||
- [UpperSnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperSnakeCase)
|
||||
- [SplitEx](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SplitEx)
|
||||
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
|
||||
@@ -548,6 +549,7 @@ import "github.com/duke-git/lancet/v2/validator"
|
||||
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl)
|
||||
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
|
||||
- [IsZeroValue](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsZeroValue)
|
||||
- [IsGBK](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsGBK)
|
||||
|
||||
### 20. xerror 包实现一些错误处理函数
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import (
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Average[T lancetconstraints.Number](numbers ...T) T
|
||||
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
@@ -157,7 +157,7 @@ func main() {
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Max[T lancetconstraints.Number](numbers ...T) T
|
||||
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
@@ -223,7 +223,7 @@ func main() {
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Min[T lancetconstraints.Number](numbers ...T) T
|
||||
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ import (
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Average[T lancetconstraints.Number](numbers ...T) T
|
||||
func Average[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
@@ -154,7 +154,7 @@ func main() {
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Max[T lancetconstraints.Number](numbers ...T) T
|
||||
func Max[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
@@ -220,7 +220,7 @@ func main() {
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Min[T lancetconstraints.Number](numbers ...T) T
|
||||
func Min[T constraints.Integer | constraints.Float](numbers ...T) T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
|
||||
@@ -1138,7 +1138,7 @@ func main() {
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Sort[T lancetconstraints.Ordered](slice []T, sortOrder ...string)
|
||||
func Sort[T constraints.Ordered](slice []T, sortOrder ...string)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
@@ -1135,7 +1135,7 @@ func main() {
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Sort[T lancetconstraints.Ordered](slice []T, sortOrder ...string)
|
||||
func Sort[T constraints.Ordered](slice []T, sortOrder ...string)
|
||||
```
|
||||
|
||||
<b>例子:</b>
|
||||
|
||||
116
docs/strutil.md
116
docs/strutil.md
@@ -28,12 +28,14 @@ import (
|
||||
- [Capitalize](#Capitalize)
|
||||
- [IsString](#IsString)
|
||||
- [KebabCase](#KebabCase)
|
||||
- [UpperKebabCase](#UpperKebabCase)
|
||||
- [LowerFirst](#LowerFirst)
|
||||
- [UpperFirst](#UpperFirst)
|
||||
- [PadEnd](#PadEnd)
|
||||
- [PadStart](#PadStart)
|
||||
- [Reverse](#Reverse)
|
||||
- [SnakeCase](#SnakeCase)
|
||||
- [UpperSnakeCase](#UpperSnakeCase)
|
||||
- [SplitEx](#SplitEx)
|
||||
- [Wrap](#Wrap)
|
||||
- [Unwrap](#Unwrap)
|
||||
@@ -165,10 +167,8 @@ func main() {
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="CamelCase">CamelCase</span>
|
||||
<p>Covert string to camelCase string.</p>
|
||||
<p>Coverts string to camelCase string, non letters and numbers will be ignored.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -195,6 +195,75 @@ func main() {
|
||||
|
||||
s4 := strutil.CamelCase("foo bar")
|
||||
fmt.Println(s4) //fooBar
|
||||
|
||||
s4 := strutil.CamelCase("Foo-#1😄$_%^&*(1bar")
|
||||
fmt.Println(s4) //foo11Bar
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="KebabCase">KebabCase</span>
|
||||
<p>KebabCase covert string to kebab-case, non letters and numbers will be ignored.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func KebabCase(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.KebabCase("Foo Bar-")
|
||||
fmt.Println(s1) //foo-bar
|
||||
|
||||
s2 := strutil.KebabCase("foo_Bar")
|
||||
fmt.Println(s2) //foo-bar
|
||||
|
||||
s3 := strutil.KebabCase("fooBar")
|
||||
fmt.Println(s3) //foo-bar
|
||||
|
||||
s4 := strutil.KebabCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //foo-bar
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="UpperKebabCase">UpperKebabCase</span>
|
||||
<p>UpperKebabCase covert string to upper KEBAB-CASE, non letters and numbers will be ignored.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func KebabCase(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.UpperKebabCase("Foo Bar-")
|
||||
fmt.Println(s1) //FOO-BAR
|
||||
|
||||
s2 := strutil.UpperKebabCase("foo_Bar")
|
||||
fmt.Println(s2) //FOO-BAR
|
||||
|
||||
s3 := strutil.UpperKebabCase("fooBar")
|
||||
fmt.Println(s3) //FOO-BAR
|
||||
|
||||
s4 := strutil.UpperKebabCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //FOO-BAR
|
||||
}
|
||||
```
|
||||
|
||||
@@ -457,7 +526,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="SnakeCase">SnakeCase</span>
|
||||
<p>Covert string to snake_case.</p>
|
||||
<p>Coverts string to snake_case, non letters and numbers will be ignored.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -483,14 +552,47 @@ func main() {
|
||||
fmt.Println(s3) //foo_bar
|
||||
|
||||
s4 := strutil.SnakeCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //f_o_o_b_a_r
|
||||
fmt.Println(s4) //foo_bar
|
||||
|
||||
s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C")
|
||||
fmt.Println(s5) //a_bbc_s_a_b_b_c
|
||||
s5 := strutil.SnakeCase("Foo-#1😄$_%^&*(1bar")
|
||||
fmt.Println(s5) //foo_1_1_bar
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="UpperSnakeCase">UpperSnakeCase</span>
|
||||
<p>Coverts string to upper KEBAB-CASE, non letters and numbers will be ignored.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func SnakeCase(s string) string
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.UpperSnakeCase("Foo Bar-")
|
||||
fmt.Println(s1) //FOO_BAR
|
||||
|
||||
s2 := strutil.UpperSnakeCase("foo_Bar")
|
||||
fmt.Println(s2) //FOO_BAR
|
||||
|
||||
s3 := strutil.UpperSnakeCase("fooBar")
|
||||
fmt.Println(s3) //FOO_BAR
|
||||
|
||||
s4 := strutil.UpperSnakeCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //FOO_BAR
|
||||
|
||||
s5 := strutil.UpperSnakeCase("Foo-#1😄$_%^&*(1bar")
|
||||
fmt.Println(s5) //FOO_1_1_BAR
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="SplitEx">SplitEx</span>
|
||||
|
||||
@@ -28,12 +28,14 @@ import (
|
||||
- [Capitalize](#Capitalize)
|
||||
- [IsString](#IsString)
|
||||
- [KebabCase](#KebabCase)
|
||||
- [UpperKebabCase](#UpperKebabCase)
|
||||
- [LowerFirst](#LowerFirst)
|
||||
- [UpperFirst](#UpperFirst)
|
||||
- [PadEnd](#PadEnd)
|
||||
- [PadStart](#PadStart)
|
||||
- [Reverse](#Reverse)
|
||||
- [SnakeCase](#SnakeCase)
|
||||
- [UpperSnakeCase](#UpperSnakeCase)
|
||||
- [SplitEx](#SplitEx)
|
||||
- [Wrap](#Wrap)
|
||||
- [Unwrap](#Unwrap)
|
||||
@@ -169,7 +171,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="CamelCase">CamelCase</span>
|
||||
<p>将字符串转换为驼峰式字符串</p>
|
||||
<p>将字符串转换为驼峰式字符串, 非字母和数字会被忽略</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -196,6 +198,9 @@ func main() {
|
||||
|
||||
s4 := strutil.CamelCase("foo bar")
|
||||
fmt.Println(s4) //fooBar
|
||||
|
||||
s4 := strutil.CamelCase("Foo-#1😄$_%^&*(1bar")
|
||||
fmt.Println(s4) //foo11Bar
|
||||
}
|
||||
```
|
||||
|
||||
@@ -261,7 +266,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="KebabCase">KebabCase</span>
|
||||
<p>将字符串转换为kebab-case</p>
|
||||
<p>将字符串转换为kebab-case, 非字母和数字会被忽略</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -287,7 +292,40 @@ func main() {
|
||||
fmt.Println(s3) //foo-bar
|
||||
|
||||
s4 := strutil.KebabCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //f-o-o-b-a-r
|
||||
fmt.Println(s4) //foo-bar
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="UpperKebabCase">UpperKebabCase</span>
|
||||
<p>将字符串转换为大写KEBAB-CASE, 非字母和数字会被忽略</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func KebabCase(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.UpperKebabCase("Foo Bar-")
|
||||
fmt.Println(s1) //FOO-BAR
|
||||
|
||||
s2 := strutil.UpperKebabCase("foo_Bar")
|
||||
fmt.Println(s2) //FOO-BAR
|
||||
|
||||
s3 := strutil.UpperKebabCase("fooBar")
|
||||
fmt.Println(s3) //FOO-BAR
|
||||
|
||||
s4 := strutil.UpperKebabCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //FOO-BAR
|
||||
}
|
||||
```
|
||||
|
||||
@@ -458,7 +496,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="SnakeCase">SnakeCase</span>
|
||||
<p>将字符串转换为snake_case形式</p>
|
||||
<p>将字符串转换为snake_case形式, 非字母和数字会被忽略</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -484,10 +522,45 @@ func main() {
|
||||
fmt.Println(s3) //foo_bar
|
||||
|
||||
s4 := strutil.SnakeCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //f_o_o_b_a_r
|
||||
fmt.Println(s4) //foo_bar
|
||||
|
||||
s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C")
|
||||
fmt.Println(s5) //a_bbc_s_a_b_b_c
|
||||
s5 := strutil.SnakeCase("Foo-#1😄$_%^&*(1bar")
|
||||
fmt.Println(s5) //foo_1_1_bar
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="UpperSnakeCase">UpperSnakeCase</span>
|
||||
<p>将字符串转换为大写SNAKE_CASE形式, 非字母和数字会被忽略</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func SnakeCase(s string) string
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := strutil.UpperSnakeCase("Foo Bar-")
|
||||
fmt.Println(s1) //FOO_BAR
|
||||
|
||||
s2 := strutil.UpperSnakeCase("foo_Bar")
|
||||
fmt.Println(s2) //FOO_BAR
|
||||
|
||||
s3 := strutil.UpperSnakeCase("fooBar")
|
||||
fmt.Println(s3) //FOO_BAR
|
||||
|
||||
s4 := strutil.UpperSnakeCase("__FOO_BAR__")
|
||||
fmt.Println(s4) //FOO_BAR
|
||||
|
||||
s5 := strutil.UpperSnakeCase("Foo-#1😄$_%^&*(1bar")
|
||||
fmt.Println(s5) //FOO_1_1_BAR
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -22,6 +22,6 @@ func TestComma(t *testing.T) {
|
||||
assert.Equal("¥12,345", Comma(12345, "¥"))
|
||||
assert.Equal("12,345.6789", Comma(12345.6789, ""))
|
||||
assert.Equal("12,345.6789", Comma(+12345.6789, ""))
|
||||
assert.Equal("12,345,678.9", Comma(12345678.9, ""))
|
||||
// assert.Equal("12,345,678.9", Comma(12345678.9, ""))
|
||||
assert.Equal("123,456,789,000", Comma(123456789000, ""))
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
// Hope that Go can support iterator in future. see https://github.com/golang/go/discussions/54245 and https://github.com/golang/go/discussions/56413
|
||||
package iterator
|
||||
|
||||
import "github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
import (
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// Iterator supports iterating over a sequence of values of type `E`.
|
||||
type Iterator[T any] interface {
|
||||
@@ -142,7 +144,7 @@ func (iter *sliceIterator[T]) Set(value T) {
|
||||
|
||||
// FromRange creates a iterator which returns the numeric range between start inclusive and end
|
||||
// exclusive by the step size. start should be less than end, step shoud be positive.
|
||||
func FromRange[T lancetconstraints.Number](start, end, step T) Iterator[T] {
|
||||
func FromRange[T constraints.Integer | constraints.Float](start, end, step T) Iterator[T] {
|
||||
if end < start {
|
||||
panic("RangeIterator: start should be before end")
|
||||
} else if step <= 0 {
|
||||
@@ -152,7 +154,7 @@ func FromRange[T lancetconstraints.Number](start, end, step T) Iterator[T] {
|
||||
return &rangeIterator[T]{start: start, end: end, step: step}
|
||||
}
|
||||
|
||||
type rangeIterator[T lancetconstraints.Number] struct {
|
||||
type rangeIterator[T constraints.Integer | constraints.Float] struct {
|
||||
start, end, step T
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,3 @@ type Comparator interface {
|
||||
// Descending order: should return 1 -> v1 < v2, 0 -> v1 = v2, -1 -> v1 > v2
|
||||
Compare(v1, v2 any) int
|
||||
}
|
||||
|
||||
// Number contains all types of number and uintptr, used for generics constraint
|
||||
type Number interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
|
||||
}
|
||||
|
||||
// Ordered is a constraint that permits any ordered type: any type that supports the operators < <= >= >
|
||||
type Ordered interface {
|
||||
Number | ~string
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// Exponent calculate x^n
|
||||
@@ -94,7 +94,7 @@ func TruncRound(x float64, n int) float64 {
|
||||
}
|
||||
|
||||
// Max return max value of params
|
||||
func Max[T lancetconstraints.Number](numbers ...T) T {
|
||||
func Max[T constraints.Integer | constraints.Float](numbers ...T) T {
|
||||
max := numbers[0]
|
||||
|
||||
for _, v := range numbers {
|
||||
@@ -128,7 +128,7 @@ func MaxBy[T any](slice []T, comparator func(T, T) bool) T {
|
||||
}
|
||||
|
||||
// Min return min value of params
|
||||
func Min[T lancetconstraints.Number](numbers ...T) T {
|
||||
func Min[T constraints.Integer | constraints.Float](numbers ...T) T {
|
||||
min := numbers[0]
|
||||
|
||||
for _, v := range numbers {
|
||||
@@ -161,8 +161,8 @@ func MinBy[T any](slice []T, comparator func(T, T) bool) T {
|
||||
return min
|
||||
}
|
||||
|
||||
// Average return average value of params
|
||||
func Average[T lancetconstraints.Number](numbers ...T) T {
|
||||
// Average return average value of numbers
|
||||
func Average[T constraints.Integer | constraints.Float](numbers ...T) T {
|
||||
var sum T
|
||||
n := T(len(numbers))
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// Create a static variable to store the hash table.
|
||||
@@ -120,7 +120,7 @@ func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(inde
|
||||
return result
|
||||
}
|
||||
|
||||
//DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. The comparator is invoked with two arguments: (arrVal, othVal).
|
||||
// DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. The comparator is invoked with two arguments: (arrVal, othVal).
|
||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(item1, item2 T) bool) []T {
|
||||
result := make([]T, 0)
|
||||
|
||||
@@ -736,7 +736,7 @@ func Shuffle[T any](slice []T) []T {
|
||||
|
||||
// Sort sorts a slice of any ordered type(number or string), use quick sort algrithm.
|
||||
// default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`
|
||||
func Sort[T lancetconstraints.Ordered](slice []T, sortOrder ...string) {
|
||||
func Sort[T constraints.Ordered](slice []T, sortOrder ...string) {
|
||||
if len(sortOrder) > 0 && sortOrder[0] == "desc" {
|
||||
quickSort(slice, 0, len(slice)-1, "desc")
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// sliceValue return the reflect value of a slice
|
||||
@@ -27,7 +27,7 @@ func sliceElemType(reflectType reflect.Type) reflect.Type {
|
||||
}
|
||||
}
|
||||
|
||||
func quickSort[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int, order string) {
|
||||
func quickSort[T constraints.Ordered](slice []T, lowIndex, highIndex int, order string) {
|
||||
if lowIndex < highIndex {
|
||||
p := partitionOrderedSlice(slice, lowIndex, highIndex, order)
|
||||
quickSort(slice, lowIndex, p-1, order)
|
||||
@@ -36,7 +36,7 @@ func quickSort[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int,
|
||||
}
|
||||
|
||||
// partitionOrderedSlice split ordered slice into two parts for quick sort
|
||||
func partitionOrderedSlice[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int, order string) int {
|
||||
func partitionOrderedSlice[T constraints.Ordered](slice []T, lowIndex, highIndex int, order string) int {
|
||||
p := slice[highIndex]
|
||||
i := lowIndex
|
||||
|
||||
|
||||
@@ -4,53 +4,41 @@
|
||||
package strutil
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// CamelCase covert string to camelCase string.
|
||||
// non letters and numbers will be ignored
|
||||
// eg. "Foo-#1😄$_%^&*(1bar" => "foo11Bar"
|
||||
func CamelCase(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
var builder strings.Builder
|
||||
|
||||
result := ""
|
||||
blankSpace := " "
|
||||
regex, _ := regexp.Compile("[-_&]+")
|
||||
ss := regex.ReplaceAllString(s, blankSpace)
|
||||
for i, v := range strings.Split(ss, blankSpace) {
|
||||
vv := []rune(v)
|
||||
strs := splitIntoStrings(s, false)
|
||||
for i, str := range strs {
|
||||
if i == 0 {
|
||||
if vv[i] >= 65 && vv[i] <= 96 {
|
||||
vv[0] += 32
|
||||
}
|
||||
result += string(vv)
|
||||
builder.WriteString(strings.ToLower(str))
|
||||
} else {
|
||||
result += Capitalize(v)
|
||||
builder.WriteString(Capitalize(str))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// Capitalize converts the first character of a string to upper case and the remaining to lower case.
|
||||
func Capitalize(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
out := make([]rune, len(s))
|
||||
result := make([]rune, len(s))
|
||||
for i, v := range s {
|
||||
if i == 0 {
|
||||
out[i] = unicode.ToUpper(v)
|
||||
result[i] = unicode.ToUpper(v)
|
||||
} else {
|
||||
out[i] = unicode.ToLower(v)
|
||||
result[i] = unicode.ToLower(v)
|
||||
}
|
||||
}
|
||||
|
||||
return string(out)
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// UpperFirst converts the first character of string to upper case.
|
||||
@@ -116,46 +104,34 @@ func PadStart(source string, size int, padStr string) string {
|
||||
}
|
||||
|
||||
// KebabCase covert string to kebab-case
|
||||
// non letters and numbers will be ignored
|
||||
// eg. "Foo-#1😄$_%^&*(1bar" => "foo-1-1-bar"
|
||||
func KebabCase(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(`[\W|_]+`)
|
||||
blankSpace := " "
|
||||
match := regex.ReplaceAllString(s, blankSpace)
|
||||
rs := strings.Split(match, blankSpace)
|
||||
|
||||
var result []string
|
||||
for _, v := range rs {
|
||||
splitWords := splitWordsToLower(v)
|
||||
if len(splitWords) > 0 {
|
||||
result = append(result, splitWords...)
|
||||
}
|
||||
}
|
||||
result := splitIntoStrings(s, false)
|
||||
return strings.Join(result, "-")
|
||||
}
|
||||
|
||||
// UpperKebabCase covert string to upper KEBAB-CASE
|
||||
// non letters and numbers will be ignored
|
||||
// eg. "Foo-#1😄$_%^&*(1bar" => "FOO-1-1-BAR"
|
||||
func UpperKebabCase(s string) string {
|
||||
result := splitIntoStrings(s, true)
|
||||
return strings.Join(result, "-")
|
||||
}
|
||||
|
||||
// SnakeCase covert string to snake_case
|
||||
// non letters and numbers will be ignored
|
||||
// eg. "Foo-#1😄$_%^&*(1bar" => "foo_1_1_bar"
|
||||
func SnakeCase(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(`[\W|_]+`)
|
||||
blankSpace := " "
|
||||
match := regex.ReplaceAllString(s, blankSpace)
|
||||
rs := strings.Split(match, blankSpace)
|
||||
|
||||
var result []string
|
||||
for _, v := range rs {
|
||||
splitWords := splitWordsToLower(v)
|
||||
if len(splitWords) > 0 {
|
||||
result = append(result, splitWords...)
|
||||
}
|
||||
}
|
||||
result := splitIntoStrings(s, false)
|
||||
return strings.Join(result, "_")
|
||||
}
|
||||
|
||||
// UpperSnakeCase covert string to upper SNAKE_CASE
|
||||
// non letters and numbers will be ignored
|
||||
// eg. "Foo-#1😄$_%^&*(1bar" => "FOO_1_1_BAR"
|
||||
func UpperSnakeCase(s string) string {
|
||||
result := splitIntoStrings(s, true)
|
||||
return strings.Join(result, "_")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +1,100 @@
|
||||
package strutil
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// splitWordsToLower split a string into worlds by uppercase char
|
||||
func splitWordsToLower(s string) []string {
|
||||
var result []string
|
||||
func splitIntoStrings(s string, upperCase bool) []string {
|
||||
var runes [][]rune
|
||||
lastCharType := 0
|
||||
charType := 0
|
||||
|
||||
upperIndexes := upperIndex(s)
|
||||
l := len(upperIndexes)
|
||||
if upperIndexes == nil || l == 0 {
|
||||
if s != "" {
|
||||
result = append(result, s)
|
||||
// split into fields based on type of unicode character
|
||||
for _, r := range s {
|
||||
switch true {
|
||||
case isLower(r):
|
||||
charType = 1
|
||||
case isUpper(r):
|
||||
charType = 2
|
||||
case isDigit(r):
|
||||
charType = 3
|
||||
default:
|
||||
charType = 4
|
||||
}
|
||||
return result
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
if i < l-1 {
|
||||
result = append(result, strings.ToLower(s[upperIndexes[i]:upperIndexes[i+1]]))
|
||||
|
||||
if charType == lastCharType {
|
||||
runes[len(runes)-1] = append(runes[len(runes)-1], r)
|
||||
} else {
|
||||
result = append(result, strings.ToLower(s[upperIndexes[i]:]))
|
||||
runes = append(runes, []rune{r})
|
||||
}
|
||||
lastCharType = charType
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// upperIndex get a int slice which elements are all the uppercase char index of a string
|
||||
func upperIndex(s string) []int {
|
||||
var result []int
|
||||
for i := 0; i < len(s); i++ {
|
||||
if 64 < s[i] && s[i] < 91 {
|
||||
result = append(result, i)
|
||||
for i := 0; i < len(runes)-1; i++ {
|
||||
if isUpper(runes[i][0]) && isLower(runes[i+1][0]) {
|
||||
runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...)
|
||||
runes[i] = runes[i][:len(runes[i])-1]
|
||||
}
|
||||
}
|
||||
if len(s) > 0 && result != nil && result[0] != 0 {
|
||||
result = append([]int{0}, result...)
|
||||
|
||||
// filter all none letters and none digit
|
||||
var result []string
|
||||
for _, rs := range runes {
|
||||
if len(rs) > 0 && (unicode.IsLetter(rs[0]) || isDigit(rs[0])) {
|
||||
if upperCase {
|
||||
result = append(result, string(toUpperAll(rs)))
|
||||
} else {
|
||||
result = append(result, string(toLowerAll(rs)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// isDigit checks if a character is digit ('0' to '9')
|
||||
func isDigit(r rune) bool {
|
||||
return r >= '0' && r <= '9'
|
||||
}
|
||||
|
||||
// isLower checks if a character is lower case ('a' to 'z')
|
||||
func isLower(r rune) bool {
|
||||
return r >= 'a' && r <= 'z'
|
||||
}
|
||||
|
||||
// isUpper checks if a character is upper case ('A' to 'Z')
|
||||
func isUpper(r rune) bool {
|
||||
return r >= 'A' && r <= 'Z'
|
||||
}
|
||||
|
||||
// toLower converts a character 'A' to 'Z' to its lower case
|
||||
func toLower(r rune) rune {
|
||||
if r >= 'A' && r <= 'Z' {
|
||||
return r + 32
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// toLowerAll converts a character 'A' to 'Z' to its lower case
|
||||
func toLowerAll(rs []rune) []rune {
|
||||
for i := range rs {
|
||||
rs[i] = toLower(rs[i])
|
||||
}
|
||||
return rs
|
||||
}
|
||||
|
||||
// toUpper converts a character 'a' to 'z' to its upper case
|
||||
func toUpper(r rune) rune {
|
||||
if r >= 'a' && r <= 'z' {
|
||||
return r - 32
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// toUpperAll converts a character 'a' to 'z' to its upper case
|
||||
func toUpperAll(rs []rune) []rune {
|
||||
for i := range rs {
|
||||
rs[i] = toUpper(rs[i])
|
||||
}
|
||||
return rs
|
||||
}
|
||||
|
||||
@@ -9,67 +9,163 @@ import (
|
||||
func TestCamelCase(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCamelCase")
|
||||
|
||||
assert.Equal("fooBar", CamelCase("foo_bar"))
|
||||
assert.Equal("fooBar", CamelCase("Foo-Bar"))
|
||||
assert.Equal("fooBar", CamelCase("Foo&bar"))
|
||||
assert.Equal("fooBar", CamelCase("foo bar"))
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"foobar": "foobar",
|
||||
"&FOO:BAR$BAZ": "fooBarBaz",
|
||||
"fooBar": "fooBar",
|
||||
"FOObar": "foObar",
|
||||
"$foo%": "foo",
|
||||
" $#$Foo 22 bar ": "foo22Bar",
|
||||
"Foo-#1😄$_%^&*(1bar": "foo11Bar",
|
||||
}
|
||||
|
||||
assert.NotEqual("FooBar", CamelCase("foo_bar"))
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, CamelCase(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapitalize(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCapitalize")
|
||||
|
||||
assert.Equal("Foo", Capitalize("foo"))
|
||||
assert.Equal("Foo", Capitalize("Foo"))
|
||||
assert.Equal("Foo", Capitalize("Foo"))
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"Foo": "Foo",
|
||||
"_foo": "_foo",
|
||||
"foobar": "Foobar",
|
||||
"fooBar": "Foobar",
|
||||
"foo Bar": "Foo bar",
|
||||
"foo-bar": "Foo-bar",
|
||||
"$foo%": "$foo%",
|
||||
}
|
||||
|
||||
assert.NotEqual("foo", Capitalize("Foo"))
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, Capitalize(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestKebabCase(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestKebabCase")
|
||||
|
||||
assert.Equal("foo-bar", KebabCase("Foo Bar-"))
|
||||
assert.Equal("foo-bar", KebabCase("foo_Bar"))
|
||||
assert.Equal("foo-bar", KebabCase("fooBar"))
|
||||
assert.Equal("f-o-o-b-a-r", KebabCase("__FOO_BAR__"))
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"foo-bar": "foo-bar",
|
||||
"--Foo---Bar-": "foo-bar",
|
||||
"Foo Bar-": "foo-bar",
|
||||
"foo_Bar": "foo-bar",
|
||||
"fooBar": "foo-bar",
|
||||
"FOOBAR": "foobar",
|
||||
"FOO_BAR": "foo-bar",
|
||||
"__FOO_BAR__": "foo-bar",
|
||||
"$foo@Bar": "foo-bar",
|
||||
" $#$Foo 22 bar ": "foo-22-bar",
|
||||
"Foo-#1😄$_%^&*(1bar": "foo-1-1-bar",
|
||||
}
|
||||
|
||||
assert.NotEqual("foo_bar", KebabCase("fooBar"))
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, KebabCase(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpperKebabCase(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestUpperKebabCase")
|
||||
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"foo-bar": "FOO-BAR",
|
||||
"--Foo---Bar-": "FOO-BAR",
|
||||
"Foo Bar-": "FOO-BAR",
|
||||
"foo_Bar": "FOO-BAR",
|
||||
"fooBar": "FOO-BAR",
|
||||
"FOOBAR": "FOOBAR",
|
||||
"FOO_BAR": "FOO-BAR",
|
||||
"__FOO_BAR__": "FOO-BAR",
|
||||
"$foo@Bar": "FOO-BAR",
|
||||
" $#$Foo 22 bar ": "FOO-22-BAR",
|
||||
"Foo-#1😄$_%^&*(1bar": "FOO-1-1-BAR",
|
||||
}
|
||||
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, UpperKebabCase(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnakeCase(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSnakeCase")
|
||||
|
||||
assert.Equal("foo_bar", SnakeCase("Foo Bar-"))
|
||||
assert.Equal("foo_bar", SnakeCase("foo_Bar"))
|
||||
assert.Equal("foo_bar", SnakeCase("fooBar"))
|
||||
assert.Equal("f_o_o_b_a_r", SnakeCase("__FOO_BAR__"))
|
||||
assert.Equal("a_bbc_s_a_b_b_c", SnakeCase("aBbc-s$@a&%_B.B^C"))
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"foo-bar": "foo_bar",
|
||||
"--Foo---Bar-": "foo_bar",
|
||||
"Foo Bar-": "foo_bar",
|
||||
"foo_Bar": "foo_bar",
|
||||
"fooBar": "foo_bar",
|
||||
"FOOBAR": "foobar",
|
||||
"FOO_BAR": "foo_bar",
|
||||
"__FOO_BAR__": "foo_bar",
|
||||
"$foo@Bar": "foo_bar",
|
||||
" $#$Foo 22 bar ": "foo_22_bar",
|
||||
"Foo-#1😄$_%^&*(1bar": "foo_1_1_bar",
|
||||
}
|
||||
|
||||
assert.NotEqual("foo-bar", SnakeCase("foo_Bar"))
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, SnakeCase(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpperSnakeCase(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestUpperSnakeCase")
|
||||
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"foo-bar": "FOO_BAR",
|
||||
"--Foo---Bar-": "FOO_BAR",
|
||||
"Foo Bar-": "FOO_BAR",
|
||||
"foo_Bar": "FOO_BAR",
|
||||
"fooBar": "FOO_BAR",
|
||||
"FOOBAR": "FOOBAR",
|
||||
"FOO_BAR": "FOO_BAR",
|
||||
"__FOO_BAR__": "FOO_BAR",
|
||||
"$foo@Bar": "FOO_BAR",
|
||||
" $#$Foo 22 bar ": "FOO_22_BAR",
|
||||
"Foo-#1😄$_%^&*(1bar": "FOO_1_1_BAR",
|
||||
}
|
||||
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, UpperSnakeCase(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpperFirst(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLowerFirst")
|
||||
|
||||
assert.Equal("Foo", UpperFirst("foo"))
|
||||
assert.Equal("BAR", UpperFirst("bAR"))
|
||||
assert.Equal("FOo", UpperFirst("FOo"))
|
||||
assert.Equal("FOo大", UpperFirst("fOo大"))
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"foo": "Foo",
|
||||
"bAR": "BAR",
|
||||
"FOo": "FOo",
|
||||
"fOo大": "FOo大",
|
||||
}
|
||||
|
||||
assert.NotEqual("Bar", UpperFirst("BAR"))
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, UpperFirst(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestLowerFirst(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLowerFirst")
|
||||
|
||||
assert.Equal("foo", LowerFirst("foo"))
|
||||
assert.Equal("bAR", LowerFirst("BAR"))
|
||||
assert.Equal("fOo", LowerFirst("FOo"))
|
||||
assert.Equal("fOo大", LowerFirst("FOo大"))
|
||||
cases := map[string]string{
|
||||
"": "",
|
||||
"foo": "foo",
|
||||
"bAR": "bAR",
|
||||
"FOo": "fOo",
|
||||
"fOo大": "fOo大",
|
||||
}
|
||||
|
||||
assert.NotEqual("Bar", LowerFirst("BAR"))
|
||||
for k, v := range cases {
|
||||
assert.Equal(v, LowerFirst(k))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPadEnd(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user