diff --git a/README.md b/README.md
index 72579369..25d4be09 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@

-[](https://github.com/duke-git/lancet/releases)
+[](https://github.com/duke-git/lancet/releases)
[](https://pkg.go.dev/github.com/duke-git/lancet)
[](https://goreportcard.com/report/github.com/duke-git/lancet)
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -484,6 +484,7 @@ import "github.com/duke-git/lancet/strutil"
- [Rotate](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Rotate)
- [TemplateReplace](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#TemplateReplace)
- [RegexMatchAllGroups](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#RegexMatchAllGroups)
+- [Cut](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Cut)
### 14. System package contain some functions about os, runtime, shell command.
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 92980862..5b194827 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -4,7 +4,7 @@

-[](https://github.com/duke-git/lancet/releases)
+[](https://github.com/duke-git/lancet/releases)
[](https://pkg.go.dev/github.com/duke-git/lancet)
[](https://goreportcard.com/report/github.com/duke-git/lancet)
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -486,6 +486,7 @@ import "github.com/duke-git/lancet/strutil"
- [Rotate](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Rotate)
- [TemplateReplace](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#TemplateReplace)
- [RegexMatchAllGroups](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#RegexMatchAllGroups)
+- [Cut](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Cut)
### 14. system 包含 os, runtime, shell command 相关函数。
diff --git a/compare/compare_internal.go b/compare/compare_internal.go
index 64a9829c..e363a183 100644
--- a/compare/compare_internal.go
+++ b/compare/compare_internal.go
@@ -37,7 +37,8 @@ func compareRefValue(operator string, leftObj, rightObj interface{}, kind reflec
case reflect.Struct:
// compare time
- if leftVal.CanConvert(timeType) {
+ // fix: issue #275
+ if canConvert(leftObj, timeType) {
timeObj1, ok := leftObj.(time.Time)
if !ok {
timeObj1 = leftVal.Convert(timeType).Interface().(time.Time)
@@ -59,7 +60,7 @@ func compareRefValue(operator string, leftObj, rightObj interface{}, kind reflec
case reflect.Slice:
// compare []byte
- if leftVal.CanConvert(bytesType) {
+ if canConvert(leftObj, bytesType) {
bytesObj1, ok := leftObj.([]byte)
if !ok {
bytesObj1 = leftVal.Convert(bytesType).Interface().([]byte)
@@ -282,3 +283,15 @@ func compareBools(operator string, left, right bool) bool {
}
return false
}
+
+// canConvert checks if the value can be converted to the target type
+func canConvert(value interface{}, targetType reflect.Type) bool {
+ v := reflect.ValueOf(value)
+
+ defer func() {
+ if r := recover(); r != nil {
+ }
+ }()
+ v.Convert(targetType)
+ return true
+}
diff --git a/convertor/convertor_internal.go b/convertor/convertor_internal.go
index 796c9d39..0f26a72c 100644
--- a/convertor/convertor_internal.go
+++ b/convertor/convertor_internal.go
@@ -240,7 +240,8 @@ func setStructField(structObj interface{}, fieldName string, fieldValue interfac
if fieldVal.Type() != val.Type() {
- if val.CanConvert(fieldVal.Type()) {
+ // fix: issue #275
+ if canConvert(fieldValue, fieldVal.Type()) {
fieldVal.Set(val.Convert(fieldVal.Type()))
return nil
}
@@ -284,3 +285,14 @@ func getFieldNameByJsonTag(structObj interface{}, jsonTag string) string {
return ""
}
+
+func canConvert(value interface{}, targetType reflect.Type) bool {
+ v := reflect.ValueOf(value)
+
+ defer func() {
+ if r := recover(); r != nil {
+ }
+ }()
+ v.Convert(targetType)
+ return true
+}
diff --git a/docs/strutil.md b/docs/strutil.md
index fc9ddbb0..f99210f8 100644
--- a/docs/strutil.md
+++ b/docs/strutil.md
@@ -66,6 +66,7 @@ import (
- [Rotate](#Rotate)
- [TemplateReplace](#TemplateReplace)
- [RegexMatchAllGroups](#RegexMatchAllGroups)
+- [Cut](#Cut)
Splits the string at the first occurrence of separator.
+ +Signature: + +```go +func Cut(str, sep string) (before, after string, found bool) +``` + +example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/strutil" +) + +func main() { + str := "hello-world" + + before, after, found := strutil.Cut("hello-world", "-") + + fmt.Println(before) + fmt.Println(after) + fmt.Println(found) + + // Output: + // hello + // world + // true +} ``` \ No newline at end of file diff --git a/docs/strutil_zh-CN.md b/docs/strutil_zh-CN.md index a33c4af3..93dbdc66 100644 --- a/docs/strutil_zh-CN.md +++ b/docs/strutil_zh-CN.md @@ -66,6 +66,7 @@ import ( - [Rotate](#Rotate) - [TemplateReplace](#TemplateReplace) - [RegexMatchAllGroups](#RegexMatchAllGroups) +- [Cut](#Cut) @@ -1572,4 +1573,37 @@ func main() { // [john.doe@example.com john.doe example com] // [jane.doe@example.com jane.doe example com] } -``` \ No newline at end of file +``` + +### Cut + +分割字符串。
+ +函数签名: + +```go +func Cut(str, sep string) (before, after string, found bool) +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/strutil" +) + +func main() { + str := "hello-world" + + before, after, found := strutil.Cut("hello-world", "-") + + fmt.Println(before) + fmt.Println(after) + fmt.Println(found) + + // Output: + // hello + // world + // true +} \ No newline at end of file diff --git a/strutil/string.go b/strutil/string.go index 870ec8bc..0da6b6c7 100644 --- a/strutil/string.go +++ b/strutil/string.go @@ -535,15 +535,22 @@ func RemoveWhiteSpace(str string, repalceAll bool) string { // SubInBetween return substring between the start and end position(excluded) of source string. func SubInBetween(str string, start string, end string) string { - if _, after, ok := strings.Cut(str, start); ok { - if before, _, ok := strings.Cut(after, end); ok { + if _, after, ok := Cut(str, start); ok { + if before, _, ok := Cut(after, end); ok { return before } } - return "" } +// Cut splits the string at the first occurrence of separator. +func Cut(str, sep string) (before, after string, found bool) { + if i := strings.Index(str, sep); i >= 0 { + return str[:i], str[i+len(sep):], true + } + return str, "", false +} + // HammingDistance calculates the Hamming distance between two strings. // The Hamming distance is the number of positions at which the corresponding symbols are different. // This func returns an error if the input strings are of unequal lengths. diff --git a/strutil/string_test.go b/strutil/string_test.go index 163c1449..424608f0 100644 --- a/strutil/string_test.go +++ b/strutil/string_test.go @@ -668,3 +668,77 @@ func TestRegexMatchAllGroups(t *testing.T) { assert.Equal(tt.expected, result) } } + +func TestCut(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestCut") + + tests := []struct { + name string + s string + sep string + before string + after string + found bool + }{ + { + name: "test with separator", + s: "hello-world", + sep: "-", + before: "hello", + after: "world", + found: true, + }, + { + name: "test without separator", + s: "helloworld", + sep: "-", + before: "helloworld", + after: "", + found: false, + }, + { + name: "test empty string", + s: "", + sep: "-", + before: "", + after: "", + found: false, + }, + { + name: "test separator at the beginning", + s: "-hello", + sep: "-", + before: "", + after: "hello", + found: true, + }, + { + name: "test separator at the end", + s: "hello-", + sep: "-", + before: "hello", + after: "", + found: true, + }, + { + name: "test multiple separators", + s: "a-b-c-d", + sep: "-", + before: "a", + after: "b-c-d", + found: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + before, after, found := Cut(tt.s, tt.sep) + assert.Equal(tt.before, before) + assert.Equal(tt.after, after) + assert.Equal(tt.found, found) + }) + } + +} diff --git a/system/os_windows.go b/system/os_windows.go index 6cd36987..f1f34f1c 100644 --- a/system/os_windows.go +++ b/system/os_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows package system