diff --git a/generic.go b/generic.go index 33715fb..7ae99fe 100644 --- a/generic.go +++ b/generic.go @@ -1,5 +1,7 @@ package helpers +import "reflect" + func Ref[T any](in T) *T { return &in } @@ -30,3 +32,21 @@ func If[T any](cond bool, vtrue, vfalse T) T { } return vfalse } + +func Coalesce[T any](input ...T) T { + var check T + for _, check = range input { + if !IsZero(check) { + return check + } + } + return check +} + +func IsZero(input any) bool { + if input == nil { + return true + } + r := reflect.ValueOf(input) + return !r.IsValid() || (r.Kind() == reflect.Pointer && r.IsNil()) || r.IsZero() +} diff --git a/generic_test.go b/generic_test.go index 85a22df..ce4d1c7 100644 --- a/generic_test.go +++ b/generic_test.go @@ -23,3 +23,28 @@ func TestIf(t *testing.T) { assert.Equal(t, test.output, result) } } + +func TestCoalesce(t *testing.T) { + tests := []struct { + input []any + output any + }{ + {[]any{"", "", "hello"}, "hello"}, + {[]any{"", "world", ""}, "world"}, + {[]any{"", "", ""}, ""}, + {[]any{0, 0, 1}, 1}, + {[]any{0, 2, 1}, 2}, + {[]any{0, 0, 0}, 0}, + {[]any{nil, nil, "hello"}, "hello"}, + {[]any{nil, "world", nil}, "world"}, + {[]any{nil, "", nil}, nil}, + {[]any{nil, nil, nil}, nil}, + {[]any{nil, 2, nil}, 2}, + {[]any{nil, 0, nil}, nil}, + } + + for _, test := range tests { + result := Coalesce(test.input...) + assert.Equal(t, test.output, result) + } +} diff --git a/strings.go b/strings.go index 45e6645..63d1936 100644 --- a/strings.go +++ b/strings.go @@ -24,12 +24,7 @@ func BufferToString(buf io.Reader) string { } func FirstStr(input ...string) string { - for _, s := range input { - if s != "" { - return s - } - } - return "" + return Coalesce(input...) } func TruncateString(input string, length int) string {