Merge branch 'master' into feat-add-trim

This commit is contained in:
Samuel Berthe
2025-09-25 04:00:12 +02:00
committed by GitHub
6 changed files with 40 additions and 16 deletions

View File

@@ -17,7 +17,6 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: 'v2.4'
args: --timeout 120s --max-same-issues 50
- name: Bearer

View File

@@ -129,7 +129,7 @@ func Try(callback func() error) (ok bool) {
ok = false
}
return
return ok
}
// Try0 has the same behavior as Try, but callback returns no variable.
@@ -327,7 +327,7 @@ func TryWithErrorValue(callback func() error) (errorValue any, ok bool) {
errorValue = err
}
return
return errorValue, ok
}
// TryCatch has the same behavior as Try, but calls the catch function in case of error.

View File

@@ -113,7 +113,7 @@ func ForEach[T any](collection []T, iteratee func(item T, index int)) {
// ForEachWhile iterates over elements of collection and invokes iteratee for each element
// collection return value decide to continue or break, like do while().
// Play: https://go.dev/play/p/QnLGt35tnow
func ForEachWhile[T any](collection []T, iteratee func(item T, index int) (goon bool)) {
func ForEachWhile[T any](collection []T, iteratee func(item T, index int) bool) {
for i := range collection {
if !iteratee(collection[i], i) {
break
@@ -571,7 +571,9 @@ func FilterReject[T any, Slice ~[]T](collection Slice, predicate func(T, int) bo
// Count counts the number of elements in the collection that equal value.
// Play: https://go.dev/play/p/Y3FlK54yveC
func Count[T comparable](collection []T, value T) (count int) {
func Count[T comparable](collection []T, value T) int {
var count int
for i := range collection {
if collection[i] == value {
count++
@@ -583,7 +585,9 @@ func Count[T comparable](collection []T, value T) (count int) {
// CountBy counts the number of elements in the collection for which predicate is true.
// Play: https://go.dev/play/p/ByQbNYQQi4X
func CountBy[T any](collection []T, predicate func(item T) bool) (count int) {
func CountBy[T any](collection []T, predicate func(item T) bool) int {
var count int
for i := range collection {
if predicate(collection[i]) {
count++

View File

@@ -1133,36 +1133,43 @@ func TestSplice(t *testing.T) {
func TestCutSuccess(t *testing.T) {
t.Parallel()
is := assert.New(t)
// case 1
actualLeft, actualRight, result := Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"a", "b"})
is.True(result)
is.Equal([]string{}, actualLeft)
is.Equal([]string{"c", "d", "e", "f", "g"}, actualRight)
// case 2
actualLeft, actualRight, result = Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"f", "g"})
is.True(result)
is.Equal([]string{"a", "b", "c", "d", "e"}, actualLeft)
is.Equal([]string{}, actualRight)
// case 3
actualLeft, actualRight, result = Cut([]string{"g"}, []string{"g"})
is.True(result)
is.Equal([]string{}, actualLeft)
is.Equal([]string{}, actualRight)
// case 4
actualLeft, actualRight, result = Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"b", "c"})
is.True(result)
is.Equal([]string{"a"}, actualLeft)
is.Equal([]string{"d", "e", "f", "g"}, actualRight)
// case 5
actualLeft, actualRight, result = Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"e", "f"})
is.True(result)
is.Equal([]string{"a", "b", "c", "d"}, actualLeft)
is.Equal([]string{"g"}, actualRight)
// case 6
actualLeft, actualRight, result = Cut([]string{"a", "b"}, []string{"b"})
is.True(result)
is.Equal([]string{"a"}, actualLeft)
is.Equal([]string{}, actualRight)
// case 7
actualLeft, actualRight, result = Cut([]string{"a", "b"}, []string{"a"})
is.True(result)
@@ -1173,16 +1180,19 @@ func TestCutSuccess(t *testing.T) {
func TestCutFail(t *testing.T) {
t.Parallel()
is := assert.New(t)
// case 1
actualLeft, actualRight, result := Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"z"})
is.False(result)
is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, actualLeft)
is.Equal([]string{}, actualRight)
// case 2
actualLeft, actualRight, result = Cut([]string{}, []string{"z"})
is.False(result)
is.Equal([]string{}, actualLeft)
is.Equal([]string{}, actualRight)
// case 3
actualLeft, actualRight, result = Cut([]string{"a"}, []string{"z"})
is.False(result)
@@ -1198,6 +1208,7 @@ type TestCutStruct struct {
func TestCutPrefix(t *testing.T) {
t.Parallel()
is := assert.New(t)
// case 1
actualAfter, result := CutPrefix(
[]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}},
@@ -1205,6 +1216,7 @@ func TestCutPrefix(t *testing.T) {
)
is.True(result)
is.Equal([]TestCutStruct{{id: 2, data: "a"}, {id: 2, data: "b"}}, actualAfter)
// case 2
actualAfter, result = CutPrefix(
[]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}},
@@ -1212,6 +1224,7 @@ func TestCutPrefix(t *testing.T) {
)
is.True(result)
is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualAfter)
// case 3
actualAfter, result = CutPrefix(
[]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}},
@@ -1219,6 +1232,7 @@ func TestCutPrefix(t *testing.T) {
)
is.False(result)
is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualAfter)
// case 4
actualAfter, result = CutPrefix(
[]TestCutStruct{},
@@ -1226,6 +1240,7 @@ func TestCutPrefix(t *testing.T) {
)
is.False(result)
is.Equal([]TestCutStruct{}, actualAfter)
// case 5
actualAfterS, result := CutPrefix([]string{"a", "a", "b"}, []string{})
is.True(result)
@@ -1235,6 +1250,7 @@ func TestCutPrefix(t *testing.T) {
func TestCutSuffix(t *testing.T) {
t.Parallel()
is := assert.New(t)
// case 1
actualBefore, result := CutSuffix(
[]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}},
@@ -1242,6 +1258,7 @@ func TestCutSuffix(t *testing.T) {
)
is.False(result)
is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualBefore)
// case 2
actualBefore, result = CutSuffix(
[]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}},
@@ -1249,6 +1266,7 @@ func TestCutSuffix(t *testing.T) {
)
is.True(result)
is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}}, actualBefore)
// case 3
actualBefore, result = CutSuffix(
[]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}},
@@ -1256,6 +1274,7 @@ func TestCutSuffix(t *testing.T) {
)
is.True(result)
is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualBefore)
// case 4
actualBefore, result = CutSuffix(
[]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}},
@@ -1263,6 +1282,7 @@ func TestCutSuffix(t *testing.T) {
)
is.False(result)
is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualBefore)
// case 5
actualAfterS, result := CutSuffix([]string{"a", "a", "b"}, []string{})
is.True(result)

View File

@@ -506,7 +506,7 @@ func TestUnzipBy(t *testing.T) {
t.Parallel()
is := assert.New(t)
r1, r2 := UnzipBy2([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}}, func(i Tuple2[string, int]) (a string, b int) {
r1, r2 := UnzipBy2([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}}, func(i Tuple2[string, int]) (string, int) {
return i.A + i.A, i.B + i.B
})

View File

@@ -115,11 +115,12 @@ func FromAnySlice[T any](in []any) (out []T, ok bool) {
}
}()
result := make([]T, len(in))
out = make([]T, len(in))
ok = true
for i := range in {
result[i] = in[i].(T) //nolint:errcheck,forcetypeassert
out[i] = in[i].(T) //nolint:errcheck,forcetypeassert
}
return result, true
return out, ok
}
// Empty returns the zero value (https://go.dev/ref/spec#The_zero_value).
@@ -145,16 +146,16 @@ func IsNotEmpty[T comparable](v T) bool {
// Coalesce returns the first non-empty arguments. Arguments must be comparable.
// Play: https://go.dev/play/p/Gyo9otyvFHH
func Coalesce[T comparable](values ...T) (result T, ok bool) {
func Coalesce[T comparable](values ...T) (T, bool) {
var zero T
for i := range values {
if values[i] != result {
result = values[i]
ok = true
return
if values[i] != zero {
return values[i], true
}
}
return
return zero, false
}
// CoalesceOrEmpty returns the first non-empty arguments. Arguments must be comparable.