mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-23 13:52:26 +08:00
feat: add Bool function to check if a value is truthy or falsy
This commit is contained in:
@@ -2,8 +2,37 @@
|
|||||||
// Use of this source code is governed by MIT license
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
// Package condition contains some functions for conditional judgment. eg. And, Or, TernaryOperator ...
|
// Package condition contains some functions for conditional judgment. eg. And, Or, TernaryOperator ...
|
||||||
|
// The implementation of this package refers to the implementation of carlmjohnson's truthy package, you may find more
|
||||||
|
// useful information in truthy(https://github.com/carlmjohnson/truthy), thanks carlmjohnson.
|
||||||
package condition
|
package condition
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// Bool returns the truthy value of anything.
|
||||||
|
// If the value's type has a Bool() bool method, the method is called and returned.
|
||||||
|
// If the type has an IsZero() bool method, the opposite value is returned.
|
||||||
|
// Slices and maps are truthy if they have a length greater than zero.
|
||||||
|
// All other types are truthy if they are not their zero value.
|
||||||
|
func Bool[T any](value T) bool {
|
||||||
|
switch m := any(value).(type) {
|
||||||
|
case interface{ Bool() bool }:
|
||||||
|
return m.Bool()
|
||||||
|
case interface{ IsZero() bool }:
|
||||||
|
return !m.IsZero()
|
||||||
|
}
|
||||||
|
return reflectValue(&value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reflectValue(vp any) bool {
|
||||||
|
switch rv := reflect.ValueOf(vp).Elem(); rv.Kind() {
|
||||||
|
case reflect.Map, reflect.Slice:
|
||||||
|
return rv.Len() != 0
|
||||||
|
default:
|
||||||
|
is := rv.IsZero()
|
||||||
|
return !is
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TernaryOperator if true return trueValue else return falseValue
|
// TernaryOperator if true return trueValue else return falseValue
|
||||||
func TernaryOperator[T any](isTrue bool, trueValue T, falseValue T) T {
|
func TernaryOperator[T any](isTrue bool, trueValue T, falseValue T) T {
|
||||||
if isTrue {
|
if isTrue {
|
||||||
|
|||||||
@@ -1,11 +1,67 @@
|
|||||||
package condition
|
package condition
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TestStruct struct{}
|
||||||
|
|
||||||
|
func TestBool(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestBool")
|
||||||
|
|
||||||
|
// bool
|
||||||
|
assert.Equal(false, Bool(false))
|
||||||
|
assert.Equal(true, Bool(true))
|
||||||
|
|
||||||
|
// integer
|
||||||
|
assert.Equal(false, Bool(0))
|
||||||
|
assert.Equal(true, Bool(1))
|
||||||
|
|
||||||
|
// float
|
||||||
|
assert.Equal(false, Bool(0.0))
|
||||||
|
assert.Equal(true, Bool(0.1))
|
||||||
|
|
||||||
|
// string
|
||||||
|
assert.Equal(false, Bool(""))
|
||||||
|
assert.Equal(true, Bool(" "))
|
||||||
|
assert.Equal(true, Bool("0"))
|
||||||
|
|
||||||
|
// slice
|
||||||
|
var nums [2]int
|
||||||
|
assert.Equal(false, Bool(nums))
|
||||||
|
nums = [2]int{0, 1}
|
||||||
|
assert.Equal(true, Bool(nums))
|
||||||
|
|
||||||
|
// map
|
||||||
|
assert.Equal(false, Bool(map[string]string{}))
|
||||||
|
assert.Equal(true, Bool(map[string]string{"a": "a"}))
|
||||||
|
|
||||||
|
// channel
|
||||||
|
var ch chan int
|
||||||
|
assert.Equal(false, Bool(ch))
|
||||||
|
ch = make(chan int)
|
||||||
|
assert.Equal(true, Bool(ch))
|
||||||
|
|
||||||
|
// interface
|
||||||
|
var err error
|
||||||
|
assert.Equal(false, Bool(err))
|
||||||
|
err = errors.New("error message")
|
||||||
|
assert.Equal(true, Bool(err))
|
||||||
|
|
||||||
|
// struct
|
||||||
|
assert.Equal(false, Bool(struct{}{}))
|
||||||
|
assert.Equal(true, Bool(time.Now()))
|
||||||
|
|
||||||
|
// struct pointer
|
||||||
|
ts := TestStruct{}
|
||||||
|
assert.Equal(false, Bool(ts))
|
||||||
|
assert.Equal(true, Bool(&ts))
|
||||||
|
}
|
||||||
|
|
||||||
func TestTernaryOperator(t *testing.T) {
|
func TestTernaryOperator(t *testing.T) {
|
||||||
assert := internal.NewAssert(t, "TernaryOperator")
|
assert := internal.NewAssert(t, "TernaryOperator")
|
||||||
trueValue := "1"
|
trueValue := "1"
|
||||||
|
|||||||
Reference in New Issue
Block a user