mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
@@ -4,9 +4,11 @@
|
||||
package strutil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// CamelCase coverts string to camelCase string. Non letters and numbers will be ignored.
|
||||
@@ -373,3 +375,67 @@ func RemoveNonPrintable(str string) string {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// StringToBytes converts a string to byte slice without a memory allocation
|
||||
func StringToBytes(str string) (b []byte) {
|
||||
sh := *(*reflect.StringHeader)(unsafe.Pointer(&str))
|
||||
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
bh.Data, bh.Len, bh.Cap = sh.Data, sh.Len, sh.Len
|
||||
return b
|
||||
}
|
||||
|
||||
// BytesToString converts a byte slice to string without a memory allocation
|
||||
func BytesToString(bytes []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&bytes))
|
||||
}
|
||||
|
||||
// IsBlank checks if a string is whitespace, empty
|
||||
func IsBlank(str string) bool {
|
||||
if len(str) == 0 {
|
||||
return true
|
||||
}
|
||||
// memory copies will occur here, but UTF8 will be compatible
|
||||
runes := []rune(str)
|
||||
for _, r := range runes {
|
||||
if !unicode.IsSpace(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasPrefixAny check if a string starts with any of an array of specified strings
|
||||
func HasPrefixAny(str string, prefixes []string) bool {
|
||||
if len(str) == 0 || len(prefixes) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, prefix := range prefixes {
|
||||
if strings.HasPrefix(str, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasSuffixAny check if a string ends with any of an array of specified strings
|
||||
func HasSuffixAny(str string, suffixes []string) bool {
|
||||
if len(str) == 0 || len(suffixes) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, suffix := range suffixes {
|
||||
if strings.HasSuffix(str, suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IndexOffset returns the index of the first instance of substr in s after offsetting the string by `idxFrom`,
|
||||
// or -1 if substr is not present in s.
|
||||
func IndexOffset(str string, substr string, idxFrom int) int {
|
||||
if idxFrom > len(str)-1 || idxFrom < 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return strings.Index(str[idxFrom:], substr) + idxFrom
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package strutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCamelCase(t *testing.T) {
|
||||
@@ -349,3 +349,52 @@ func TestRemoveNonPrintable(t *testing.T) {
|
||||
assert.Equal("hello world", RemoveNonPrintable("hello\u00a0 \u200bworld\n"))
|
||||
assert.Equal("你好😄", RemoveNonPrintable("你好😄"))
|
||||
}
|
||||
|
||||
func TestString2Bytes(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestString2Bytes")
|
||||
str := "abc"
|
||||
bytes := StringToBytes(str)
|
||||
assert.Equal(reflect.DeepEqual(bytes, []byte{'a', 'b', 'c'}), true)
|
||||
}
|
||||
|
||||
func TestBytes2String(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBytes2String")
|
||||
bytes := []byte{'a', 'b', 'c'}
|
||||
str := BytesToString(bytes)
|
||||
assert.Equal(str == "abc", true)
|
||||
}
|
||||
|
||||
func TestIsBlank(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIsBlank")
|
||||
assert.Equal(IsBlank(""), true)
|
||||
assert.Equal(IsBlank("\t\v\f\n"), true)
|
||||
assert.Equal(IsBlank(" 中文"), false)
|
||||
}
|
||||
|
||||
func TestHasPrefixAny(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestHasPrefixAny")
|
||||
str := "foo bar"
|
||||
prefixes := []string{"fo", "xyz", "hello"}
|
||||
notMatches := []string{"oom", "world"}
|
||||
assert.Equal(HasPrefixAny(str, prefixes), true)
|
||||
assert.Equal(HasPrefixAny(str, notMatches), false)
|
||||
}
|
||||
|
||||
func TestHasSuffixAny(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestHasSuffixAny")
|
||||
str := "foo bar"
|
||||
suffixes := []string{"bar", "xyz", "hello"}
|
||||
notMatches := []string{"oom", "world"}
|
||||
assert.Equal(HasSuffixAny(str, suffixes), true)
|
||||
assert.Equal(HasSuffixAny(str, notMatches), false)
|
||||
}
|
||||
|
||||
func TestIndexOffset(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIndexOffset")
|
||||
str := "foo bar hello world"
|
||||
assert.Equal(IndexOffset(str, "o", 5), 12)
|
||||
assert.Equal(IndexOffset(str, "o", 0), 1)
|
||||
assert.Equal(IndexOffset(str, "d", len(str)-1), len(str)-1)
|
||||
assert.Equal(IndexOffset(str, "d", len(str)), -1)
|
||||
assert.Equal(IndexOffset(str, "f", -1), -1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user