diff options
Diffstat (limited to 'utils/toml/defaults.go')
| -rw-r--r-- | utils/toml/defaults.go | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/utils/toml/defaults.go b/utils/toml/defaults.go new file mode 100644 index 0000000..e9ef032 --- /dev/null +++ b/utils/toml/defaults.go @@ -0,0 +1,64 @@ +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() +} |
