// Filename: internal/pkg/reflectutil/structs.go package reflectutil import ( "fmt" "reflect" "strconv" ) // SetFieldFromString sets a struct field's value from a string. func SetFieldFromString(field reflect.Value, value string) error { if !field.CanSet() { return fmt.Errorf("cannot set field") } switch field.Kind() { case reflect.Int, reflect.Int64: intVal, err := strconv.ParseInt(value, 10, 64) if err != nil { return err } field.SetInt(intVal) case reflect.String: field.SetString(value) case reflect.Bool: boolVal, err := strconv.ParseBool(value) if err != nil { return err } field.SetBool(boolVal) default: return fmt.Errorf("unsupported field type: %s", field.Type()) } return nil } // FieldTypeToString converts a reflect.Type to a simple string representation. func FieldTypeToString(t reflect.Type) string { switch t.Kind() { case reflect.Int, reflect.Int64: return "int" case reflect.String: return "string" case reflect.Bool: return "bool" default: return "unknown" } } // MergeNilFields uses reflection to merge non-nil pointer fields from 'override' into 'base'. // Both base and override must be pointers to structs of the same type. func MergeNilFields(base, override interface{}) error { baseVal := reflect.ValueOf(base) overrideVal := reflect.ValueOf(override) if baseVal.Kind() != reflect.Ptr || overrideVal.Kind() != reflect.Ptr { return fmt.Errorf("base and override must be pointers") } baseElem := baseVal.Elem() overrideElem := overrideVal.Elem() if baseElem.Kind() != reflect.Struct || overrideElem.Kind() != reflect.Struct { return fmt.Errorf("base and override must be pointers to structs") } if baseElem.Type() != overrideElem.Type() { return fmt.Errorf("base and override must be of the same struct type") } for i := 0; i < overrideElem.NumField(); i++ { overrideField := overrideElem.Field(i) if overrideField.Kind() == reflect.Ptr && !overrideField.IsNil() { baseField := baseElem.Field(i) if baseField.CanSet() { baseField.Set(overrideField) } } } return nil }