From 21b0251df73404fbff7f5e1c138d66d5b7c0093d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 2 Oct 2023 01:43:03 +0200 Subject: [PATCH] reflect utils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- pkg/utils/reflect/kind.go | 12 +++++++++++ pkg/utils/reflect/match.go | 42 +++++++++++++++++++++++++++++++++++++ pkg/utils/reflect/number.go | 18 ++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 pkg/utils/reflect/kind.go create mode 100644 pkg/utils/reflect/match.go create mode 100644 pkg/utils/reflect/number.go diff --git a/pkg/utils/reflect/kind.go b/pkg/utils/reflect/kind.go new file mode 100644 index 00000000..01aa09b4 --- /dev/null +++ b/pkg/utils/reflect/kind.go @@ -0,0 +1,12 @@ +package reflect + +import ( + "reflect" +) + +func GetKind(value interface{}) reflect.Kind { + if value == nil { + return reflect.Invalid + } + return reflect.TypeOf(value).Kind() +} diff --git a/pkg/utils/reflect/match.go b/pkg/utils/reflect/match.go new file mode 100644 index 00000000..2d26a97f --- /dev/null +++ b/pkg/utils/reflect/match.go @@ -0,0 +1,42 @@ +package reflect + +import ( + "fmt" + "reflect" +) + +func MatchScalar(expected, actual interface{}) (bool, error) { + if actual == nil && expected == nil { + return true, nil + } + if actual == expected { + return true, nil + } + // if they are the same type we can use reflect.DeepEqual + if reflect.TypeOf(expected) == reflect.TypeOf(actual) { + return reflect.DeepEqual(expected, actual), nil + } + e := reflect.ValueOf(expected) + a := reflect.ValueOf(actual) + if !a.IsValid() && !e.IsValid() { + return true, nil + } + if a.CanComplex() && e.CanComplex() { + return a.Complex() == e.Complex(), nil + } + if a.CanFloat() && e.CanFloat() { + return a.Float() == e.Float(), nil + } + if a.CanInt() && e.CanInt() { + return a.Int() == e.Int(), nil + } + if a.CanUint() && e.CanUint() { + return a.Uint() == e.Uint(), nil + } + if a, ok := ToNumber(a); ok { + if e, ok := ToNumber(e); ok { + return a == e, nil + } + } + return false, fmt.Errorf("types are not comparable, %s - %s", GetKind(expected), GetKind(actual)) +} diff --git a/pkg/utils/reflect/number.go b/pkg/utils/reflect/number.go new file mode 100644 index 00000000..74f33a1b --- /dev/null +++ b/pkg/utils/reflect/number.go @@ -0,0 +1,18 @@ +package reflect + +import ( + "reflect" +) + +func ToNumber(value reflect.Value) (float64, bool) { + if value.CanFloat() { + return value.Float(), true + } + if value.CanInt() { + return float64(value.Int()), true + } + if value.CanUint() { + return float64(value.Uint()), true + } + return 0, false +}