mirror of
https://github.com/hanzoai/orm.git
synced 2026-10-30 15:01:22 +00:00
Modules declare go 1.27.1 and the build images follow. go fix applied the modernizers: any, reflect.TypeFor, the atomic types, WaitGroup.Go, the reflect field iterators, CutPrefix, SplitSeq, strings.Builder and range over int. omitzero is not applied, since it changes what the JSON says. Co-authored-by: Hanzo Dev <[email protected]>
90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
package orm
|
|
|
|
import (
|
|
"reflect"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// ApplyDefaults sets default values on entity from:
|
|
// 1. orm:"default:value" struct tags (parsed at registration)
|
|
// 2. Defaulter interface (custom Defaults() method)
|
|
func ApplyDefaults[T any](entity *T) {
|
|
var zero T
|
|
typ := reflect.TypeOf(zero)
|
|
if typ.Kind() == reflect.Pointer {
|
|
typ = typ.Elem()
|
|
}
|
|
|
|
meta, ok := LookupType(typ)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
val := reflect.ValueOf(entity).Elem()
|
|
|
|
// Apply tag-based defaults
|
|
for fieldName, defaultVal := range meta.Defaults {
|
|
f := val.FieldByName(fieldName)
|
|
if !f.IsValid() || !f.CanSet() {
|
|
continue
|
|
}
|
|
|
|
// Only set if the field is zero-valued
|
|
if !f.IsZero() {
|
|
continue
|
|
}
|
|
|
|
setFieldFromString(f, defaultVal)
|
|
}
|
|
|
|
// Apply custom defaults function from registration
|
|
if meta.DefaultsFn != nil {
|
|
meta.DefaultsFn(entity)
|
|
}
|
|
|
|
// Apply Defaulter interface
|
|
if d, ok := any(entity).(Defaulter); ok {
|
|
d.Defaults()
|
|
}
|
|
}
|
|
|
|
// setFieldFromString sets a reflect.Value from a string representation.
|
|
func setFieldFromString(f reflect.Value, s string) {
|
|
switch f.Kind() {
|
|
case reflect.String:
|
|
f.SetString(s)
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
if f.Type() == reflect.TypeFor[time.Duration]() {
|
|
d, err := time.ParseDuration(s)
|
|
if err == nil {
|
|
f.Set(reflect.ValueOf(d))
|
|
}
|
|
return
|
|
}
|
|
n, err := strconv.ParseInt(s, 10, 64)
|
|
if err == nil {
|
|
f.SetInt(n)
|
|
}
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
n, err := strconv.ParseUint(s, 10, 64)
|
|
if err == nil {
|
|
f.SetUint(n)
|
|
}
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
n, err := strconv.ParseFloat(s, 64)
|
|
if err == nil {
|
|
f.SetFloat(n)
|
|
}
|
|
|
|
case reflect.Bool:
|
|
b, err := strconv.ParseBool(s)
|
|
if err == nil {
|
|
f.SetBool(b)
|
|
}
|
|
}
|
|
}
|