diff --git a/pkg/conv/conv.go b/pkg/conv/conv.go index d623b18c8..4b62e6732 100644 --- a/pkg/conv/conv.go +++ b/pkg/conv/conv.go @@ -62,10 +62,29 @@ func StructToFlatMap(obj any) map[string]any { for k, v := range nestedMap { result[fieldName+"."+k] = v } - } else if (field.Kind() == reflect.Ptr || - field.Kind() == reflect.Array || - field.Kind() == reflect.Slice || - field.Kind() == reflect.Map) && field.IsNil() { + continue + } + + if field.Kind() == reflect.Ptr { + if field.IsNil() { + result[fieldName] = nil + continue + } + + // If the pointer is to a struct, flatten it as well + if field.Elem().Kind() == reflect.Struct { + nestedMap := StructToFlatMap(field.Elem().Interface()) + for k, v := range nestedMap { + result[fieldName+"."+k] = v + } + continue + } + + result[fieldName] = field.Elem().Interface() + continue + } + + if (field.Kind() == reflect.Slice || field.Kind() == reflect.Map) && field.IsNil() { result[fieldName] = nil } else { result[fieldName] = field.Interface() diff --git a/pkg/conv/conv_test.go b/pkg/conv/conv_test.go new file mode 100644 index 000000000..819149983 --- /dev/null +++ b/pkg/conv/conv_test.go @@ -0,0 +1,40 @@ +package conv + +import "testing" + +func TestStructToFlatMapArrayField(t *testing.T) { + type Example struct { + Numbers [2]int + } + defer func() { + if r := recover(); r != nil { + t.Fatalf("StructToFlatMap panicked: %v", r) + } + }() + _ = StructToFlatMap(Example{Numbers: [2]int{1, 2}}) +} + +func TestStructToFlatMapPointerStruct(t *testing.T) { + type Inner struct { + Name string + } + type Outer struct { + Inner *Inner + } + + m := StructToFlatMap(Outer{Inner: &Inner{Name: "value"}}) + if v, ok := m["Inner.Name"]; !ok || v != "value" { + t.Fatalf("expected Inner.Name to be 'value', got %v", m) + } +} + +func TestStructToFlatMapNilPointer(t *testing.T) { + type Outer struct { + Inner *int + } + + m := StructToFlatMap(Outer{}) + if v, ok := m["Inner"]; !ok || v != nil { + t.Fatalf("expected Inner to be nil, got %v", m) + } +}