From 06a37f37b7bf58f3630babd9701bc1b43da1292a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Sat, 19 Nov 2022 16:26:45 +0100 Subject: [PATCH] v0.0.20 --- dataext/merge.go | 35 ++++++++++++++++++++++ dataext/merge_test.go | 70 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 dataext/merge.go create mode 100644 dataext/merge_test.go diff --git a/dataext/merge.go b/dataext/merge.go new file mode 100644 index 0000000..0ad5156 --- /dev/null +++ b/dataext/merge.go @@ -0,0 +1,35 @@ +package dataext + +import ( + "reflect" +) + +func ObjectMerge[T1 any, T2 any](base T1, override T2) T1 { + + reflBase := reflect.ValueOf(&base).Elem() + reflOvrd := reflect.ValueOf(&override).Elem() + + for i := 0; i < reflBase.NumField(); i++ { + + fieldBase := reflBase.Field(i) + fieldOvrd := reflOvrd.Field(i) + + if fieldBase.Kind() != reflect.Ptr || fieldOvrd.Kind() != reflect.Ptr { + continue + } + + kindBase := fieldBase.Type().Elem().Kind() + kindOvrd := fieldOvrd.Type().Elem().Kind() + + if kindBase != kindOvrd { + continue + } + + if !fieldOvrd.IsNil() { + fieldBase.Set(fieldOvrd.Elem().Addr()) + } + + } + + return base +} diff --git a/dataext/merge_test.go b/dataext/merge_test.go new file mode 100644 index 0000000..f5b1031 --- /dev/null +++ b/dataext/merge_test.go @@ -0,0 +1,70 @@ +package dataext + +import ( + "gogs.mikescher.com/BlackForestBytes/goext/langext" + "testing" +) + +func TestObjectMerge(t *testing.T) { + type A struct { + Field1 *int + Field2 *string + Field3 *float64 + Field4 *bool + OnlyA int64 + DiffType int + } + type B struct { + Field1 *int + Field2 *string + Field3 *float64 + Field4 *bool + OnlyB int64 + DiffType string + } + + valueA := A{ + Field1: nil, + Field2: langext.Ptr("99"), + Field3: langext.Ptr(12.2), + Field4: nil, + OnlyA: 1, + DiffType: 2, + } + + valueB := B{ + Field1: langext.Ptr(12), + Field2: nil, + Field3: langext.Ptr(13.2), + Field4: nil, + OnlyB: 1, + DiffType: "X", + } + + valueMerge := ObjectMerge(valueA, valueB) + + assertPtrEqual(t, "Field1", valueMerge.Field1, valueB.Field1) + assertPtrEqual(t, "Field2", valueMerge.Field2, valueA.Field2) + assertPtrEqual(t, "Field3", valueMerge.Field3, valueB.Field3) + assertPtrEqual(t, "Field4", valueMerge.Field4, nil) + +} + +func assertPtrEqual[T1 comparable](t *testing.T, ident string, actual *T1, expected *T1) { + if actual == nil && expected == nil { + return + } + if actual != nil && expected != nil { + if *actual != *expected { + t.Errorf("[%s] values differ: Actual: '%v', Expected: '%v'", ident, *actual, *expected) + } else { + return + } + } + if actual == nil && expected != nil { + t.Errorf("[%s] values differ: Actual: nil, Expected: not-nil", ident) + } + if actual != nil && expected == nil { + t.Errorf("[%s] values differ: Actual: not-nil, Expected: nil", ident) + } +}