-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstruct.go
More file actions
103 lines (90 loc) · 2.84 KB
/
struct.go
File metadata and controls
103 lines (90 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package populate_struct
import (
"fmt"
"log"
"reflect"
"strconv"
"strings"
)
// StructToMap converts a struct to a map[string]string using the struct's JSON tags
func StructToMap(data any, prefix ...string) map[string]string {
result := make(map[string]string)
value := reflect.ValueOf(data)
// Handle pointers by dereferencing
if value.Kind() == reflect.Ptr {
value = value.Elem()
}
// Ensure the value is a struct
if value.Kind() != reflect.Struct {
panic(fmt.Sprintf("StructToMap only accepts structs or pointers to structs; got %T", data))
}
t := value.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fieldValue := value.Field(i)
// Get the json tag name
jsonTag := field.Tag.Get("json")
if jsonTag == "" {
jsonTag = field.Name
} else if len(strings.Split(jsonTag, ",")) > 1 {
jsonTag = strings.Split(jsonTag, ",")[0]
}
// Construct the full key using the prefix and json tag
fullKey := jsonTag
if len(prefix) > 0 {
fullKey = prefix[0] + "." + jsonTag
}
switch fieldValue.Kind() {
case reflect.Struct:
// Recursively process nested structs
nestedMap := StructToMap(fieldValue.Interface(), fullKey)
for k, v := range nestedMap {
result[k] = v
}
case reflect.Ptr:
// Handle pointer to a struct or a value
if !fieldValue.IsNil() {
dereferencedValue := fieldValue.Elem()
if dereferencedValue.Kind() == reflect.Struct {
nestedMap := StructToMap(dereferencedValue.Interface(), fullKey)
for k, v := range nestedMap {
result[k] = v
}
} else {
result[fullKey] = fmt.Sprintf("%v", dereferencedValue.Interface())
}
}
case reflect.Interface:
// Handle interface fields by processing their concrete value
if !fieldValue.IsNil() {
interfaceValue := fieldValue.Interface()
// Handle the case where the interface holds a struct (like helmValueRedis)
nestedMap := StructToMap(interfaceValue, fullKey)
for k, v := range nestedMap {
result[k] = v
}
}
case reflect.Slice:
// Handle slices/arrays
result[fullKey] = fmt.Sprintf("%q", fieldValue)
// for j := 0; j < fieldValue.Len(); j++ {
// item := fieldValue.Index(j)
// result[fmt.Sprintf("%s[%d]", fullKey, j)] = fmt.Sprintf("%v", item.Interface())
// }
case reflect.Bool:
// Convert boolean to string
result[fullKey] = strconv.FormatBool(fieldValue.Bool())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
// Convert int to string
result[fullKey] = strconv.FormatInt(fieldValue.Int(), 10)
case reflect.String:
// Convert string to string (directly assign)
result[fullKey] = fieldValue.String()
default:
// Handle other kinds of fields by converting them to string
log.Println("WARN: StructToMap unsupported type")
result[fullKey] = fmt.Sprintf("%v", fieldValue.Interface())
}
}
return result
}