package toml import ( "reflect" "strconv" ) func ApplyDefaults(target any) { targetValue := reflect.ValueOf(target) if targetValue.Kind() != reflect.Pointer || targetValue.Elem().Kind() != reflect.Struct { return } applyStructDefaults(targetValue.Elem()) } func applyStructDefaults(structValue reflect.Value) { structType := structValue.Type() for fieldIndex := range structType.NumField() { fieldValue := structValue.Field(fieldIndex) fieldDescriptor := structType.Field(fieldIndex) if !fieldValue.CanSet() { continue } if fieldValue.Kind() == reflect.Struct { applyStructDefaults(fieldValue) continue } defaultValue := fieldDescriptor.Tag.Get("default") if defaultValue == "" { continue } setDefaultValue(fieldValue, defaultValue) } } func setDefaultValue(field reflect.Value, defaultValue string) { if !isZeroValue(field) { return } switch field.Kind() { case reflect.String: field.SetString(defaultValue) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if parsed, parseError := strconv.ParseInt(defaultValue, 10, 64); parseError == nil { field.SetInt(parsed) } case reflect.Bool: if parsed, parseError := strconv.ParseBool(defaultValue); parseError == nil { field.SetBool(parsed) } } } func isZeroValue(field reflect.Value) bool { return field.IsZero() }