package validation import ( "errors" "fmt" "reflect" ) func GetUpdatedValue[T any](def T, new *T) T { if new != nil { return *new } return def } func DeduplicateArray[T comparable](arr []T) []T { occurred := make(map[T]bool) result := []T{} for _, value := range arr { if !occurred[value] { occurred[value] = true result = append(result, value) } } return result } func NormalizeInClosedInterval(updated **int32, current int32, min int32, max int32) error { if updated == nil || *updated == nil { return nil } if **updated == current { *updated = nil return nil } if **updated < min || **updated > max { return fmt.Errorf("update must be in range: %d <= update <= %d", min, max) } return nil } func AreAllPointersNilExcept[T any](s T, exceptions ...string) bool { v := reflect.ValueOf(s) if v.Kind() == reflect.Ptr { v = v.Elem() } if v.Kind() != reflect.Struct { return false } exceptFields := make(map[string]bool) for _, name := range exceptions { exceptFields[name] = true } t := v.Type() for i := 0; i < v.NumField(); i++ { field := v.Field(i) fieldName := t.Field(i).Name if exceptFields[fieldName] || field.Kind() != reflect.Ptr { continue } if !field.IsNil() { return false } } return true } func GetFieldName[T any](s T, field any) (string, error) { v := reflect.ValueOf(s) if v.Kind() == reflect.Ptr { v = v.Elem() } t := v.Type() fieldValue := reflect.ValueOf(field) for i := 0; i < v.NumField(); i++ { f := v.Field(i) if f.Kind() == reflect.Ptr && f.Pointer() == fieldValue.Pointer() || f.Kind() != reflect.Ptr && f.CanAddr() && f.Addr().Pointer() == fieldValue.Pointer() { return t.Field(i).Name, nil } } return "", errors.New("field not found") }