2025-01-23 14:56:20 +00:00
|
|
|
package validation
|
|
|
|
|
|
2025-02-11 15:22:59 +00:00
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"reflect"
|
|
|
|
|
)
|
2025-01-23 14:56:20 +00:00
|
|
|
|
|
|
|
|
func GetUpdatedValue[T any](def T, new *T) T {
|
|
|
|
|
if new != nil {
|
|
|
|
|
return *new
|
|
|
|
|
}
|
2025-06-11 12:01:04 +00:00
|
|
|
|
2025-01-23 14:56:20 +00:00
|
|
|
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
|
|
|
|
|
}
|
2025-02-11 15:22:59 +00:00
|
|
|
|
|
|
|
|
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")
|
|
|
|
|
}
|