router/common.go

95 lines
2.1 KiB
Go
Raw Normal View History

2024-10-08 21:57:25 +00:00
package router
import (
"fmt"
"reflect"
2024-10-10 18:26:07 +00:00
"strings"
2024-10-08 21:57:25 +00:00
)
2024-10-09 01:06:53 +00:00
type genericValues map[string][]string
2024-10-08 21:57:25 +00:00
2024-10-10 18:26:07 +00:00
func (gv genericValues) Marshal(data any, tag string) (err error) {
2024-10-08 21:57:25 +00:00
if gv == nil {
2024-10-09 01:06:53 +00:00
gv = make(genericValues)
2024-10-08 21:57:25 +00:00
}
d := reflect.ValueOf(data)
2024-10-09 02:30:29 +00:00
if d.Kind() == reflect.Pointer || d.Kind() == reflect.Interface {
d = d.Elem()
}
2024-10-08 21:57:25 +00:00
if d.Kind() != reflect.Struct {
2024-10-08 22:04:57 +00:00
err = fmt.Errorf("expected struct input for data")
return
2024-10-08 21:57:25 +00:00
}
for i := 0; i < d.NumField(); i++ {
key, ok := d.Type().Field(i).Tag.Lookup(tag)
if !ok || key == "" {
continue
}
v := make([]string, 0)
val := d.Field(i)
if val.Kind() == reflect.Pointer || val.Kind() == reflect.Interface {
val = val.Elem()
}
if val.Kind() == reflect.Slice || val.Kind() == reflect.Array {
for j := 0; j < val.Len(); j++ {
item := val.Index(j)
if item.Kind() == reflect.Pointer || item.Kind() == reflect.Interface {
item = item.Elem()
}
v = append(v, fmt.Sprintf("%s", item.Interface()))
}
} else {
v = append(v, fmt.Sprintf("%s", val.Interface()))
}
gv[key] = v
}
2024-10-08 22:04:57 +00:00
return
2024-10-08 21:57:25 +00:00
}
2024-10-10 18:26:07 +00:00
func (gv genericValues) Unmarshal(data any, tag string) (err error) {
if gv == nil {
err = fmt.Errorf("expected map to exist")
return
}
d := reflect.ValueOf(data)
if d.Kind() != reflect.Pointer || d.Kind() != reflect.Interface {
err = fmt.Errorf("expected pointer for data")
return
}
d = d.Elem()
if d.Kind() != reflect.Struct {
err = fmt.Errorf("expected struct input for data")
return
}
for key, value := range gv {
var v reflect.Value
if len(value) == 1 {
v = reflect.ValueOf(value[0])
} else {
v = reflect.ValueOf(value)
}
for i := 0; i < d.NumField(); i++ {
k, ok := d.Type().Field(i).Tag.Lookup(tag)
if !ok || k != key {
continue
}
val := d.Field(i)
if val.Kind() == reflect.Pointer || val.Kind() == reflect.Interface {
val = val.Elem()
}
if !val.CanSet() {
err = fmt.Errorf("could not set value for %s", d.Type().Field(i).Name)
}
switch val.Kind() {
case reflect.String:
val.Set(reflect.ValueOf(strings.Join(value, "; ")))
default:
if v.CanConvert(val.Type()) {
val.Set(v.Convert(val.Type()))
}
}
}
}
return
}