New
This commit is contained in:
81
internal/pkg/reflectutil/structs.go
Normal file
81
internal/pkg/reflectutil/structs.go
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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
|
||||
}
|
||||
57
internal/pkg/stringutil/string.go
Normal file
57
internal/pkg/stringutil/string.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Filename: internal/pkg/stringutil/string.go
|
||||
package stringutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MaskAPIKey masks an API key for safe logging.
|
||||
func MaskAPIKey(key string) string {
|
||||
length := len(key)
|
||||
if length <= 8 {
|
||||
return key
|
||||
}
|
||||
return fmt.Sprintf("%s****%s", key[:4], key[length-4:])
|
||||
}
|
||||
|
||||
// TruncateString shortens a string to a maximum length.
|
||||
func TruncateString(s string, maxLength int) string {
|
||||
if len(s) > maxLength {
|
||||
return s[:maxLength]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SplitAndTrim splits a string by a separator
|
||||
func SplitAndTrim(s string, sep string) []string {
|
||||
if s == "" {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
parts := strings.Split(s, sep)
|
||||
result := make([]string, 0, len(parts))
|
||||
|
||||
for _, part := range parts {
|
||||
trimmed := strings.TrimSpace(part)
|
||||
if trimmed != "" {
|
||||
result = append(result, trimmed)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// StringToSet converts a separator-delimited string into a set
|
||||
func StringToSet(s string, sep string) map[string]struct{} {
|
||||
parts := SplitAndTrim(s, sep)
|
||||
if len(parts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
set := make(map[string]struct{}, len(parts))
|
||||
for _, part := range parts {
|
||||
set[part] = struct{}{}
|
||||
}
|
||||
return set
|
||||
}
|
||||
Reference in New Issue
Block a user