summaryrefslogtreecommitdiffstats
path: root/dependencies/pkg/mod/github.com/creasty/defaults@v1.6.0/defaults.go
diff options
context:
space:
mode:
Diffstat (limited to 'dependencies/pkg/mod/github.com/creasty/defaults@v1.6.0/defaults.go')
-rw-r--r--dependencies/pkg/mod/github.com/creasty/defaults@v1.6.0/defaults.go221
1 files changed, 221 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/github.com/creasty/defaults@v1.6.0/defaults.go b/dependencies/pkg/mod/github.com/creasty/defaults@v1.6.0/defaults.go
new file mode 100644
index 0000000..3bb2c22
--- /dev/null
+++ b/dependencies/pkg/mod/github.com/creasty/defaults@v1.6.0/defaults.go
@@ -0,0 +1,221 @@
+package defaults
+
+import (
+ "encoding/json"
+ "errors"
+ "reflect"
+ "strconv"
+ "time"
+)
+
+var (
+ errInvalidType = errors.New("not a struct pointer")
+)
+
+const (
+ fieldName = "default"
+)
+
+// Set initializes members in a struct referenced by a pointer.
+// Maps and slices are initialized by `make` and other primitive types are set with default values.
+// `ptr` should be a struct pointer
+func Set(ptr interface{}) error {
+ if reflect.TypeOf(ptr).Kind() != reflect.Ptr {
+ return errInvalidType
+ }
+
+ v := reflect.ValueOf(ptr).Elem()
+ t := v.Type()
+
+ if t.Kind() != reflect.Struct {
+ return errInvalidType
+ }
+
+ for i := 0; i < t.NumField(); i++ {
+ if defaultVal := t.Field(i).Tag.Get(fieldName); defaultVal != "-" {
+ if err := setField(v.Field(i), defaultVal); err != nil {
+ return err
+ }
+ }
+ }
+ callSetter(ptr)
+ return nil
+}
+
+// MustSet function is a wrapper of Set function
+// It will call Set and panic if err not equals nil.
+func MustSet(ptr interface{}) {
+ if err := Set(ptr); err != nil {
+ panic(err)
+ }
+}
+
+func setField(field reflect.Value, defaultVal string) error {
+ if !field.CanSet() {
+ return nil
+ }
+
+ if !shouldInitializeField(field, defaultVal) {
+ return nil
+ }
+
+ isInitial := isInitialValue(field)
+ if isInitial {
+ switch field.Kind() {
+ case reflect.Bool:
+ if val, err := strconv.ParseBool(defaultVal); err == nil {
+ field.Set(reflect.ValueOf(val).Convert(field.Type()))
+ }
+ case reflect.Int:
+ if val, err := strconv.ParseInt(defaultVal, 0, strconv.IntSize); err == nil {
+ field.Set(reflect.ValueOf(int(val)).Convert(field.Type()))
+ }
+ case reflect.Int8:
+ if val, err := strconv.ParseInt(defaultVal, 0, 8); err == nil {
+ field.Set(reflect.ValueOf(int8(val)).Convert(field.Type()))
+ }
+ case reflect.Int16:
+ if val, err := strconv.ParseInt(defaultVal, 0, 16); err == nil {
+ field.Set(reflect.ValueOf(int16(val)).Convert(field.Type()))
+ }
+ case reflect.Int32:
+ if val, err := strconv.ParseInt(defaultVal, 0, 32); err == nil {
+ field.Set(reflect.ValueOf(int32(val)).Convert(field.Type()))
+ }
+ case reflect.Int64:
+ if val, err := time.ParseDuration(defaultVal); err == nil {
+ field.Set(reflect.ValueOf(val).Convert(field.Type()))
+ } else if val, err := strconv.ParseInt(defaultVal, 0, 64); err == nil {
+ field.Set(reflect.ValueOf(val).Convert(field.Type()))
+ }
+ case reflect.Uint:
+ if val, err := strconv.ParseUint(defaultVal, 0, strconv.IntSize); err == nil {
+ field.Set(reflect.ValueOf(uint(val)).Convert(field.Type()))
+ }
+ case reflect.Uint8:
+ if val, err := strconv.ParseUint(defaultVal, 0, 8); err == nil {
+ field.Set(reflect.ValueOf(uint8(val)).Convert(field.Type()))
+ }
+ case reflect.Uint16:
+ if val, err := strconv.ParseUint(defaultVal, 0, 16); err == nil {
+ field.Set(reflect.ValueOf(uint16(val)).Convert(field.Type()))
+ }
+ case reflect.Uint32:
+ if val, err := strconv.ParseUint(defaultVal, 0, 32); err == nil {
+ field.Set(reflect.ValueOf(uint32(val)).Convert(field.Type()))
+ }
+ case reflect.Uint64:
+ if val, err := strconv.ParseUint(defaultVal, 0, 64); err == nil {
+ field.Set(reflect.ValueOf(val).Convert(field.Type()))
+ }
+ case reflect.Uintptr:
+ if val, err := strconv.ParseUint(defaultVal, 0, strconv.IntSize); err == nil {
+ field.Set(reflect.ValueOf(uintptr(val)).Convert(field.Type()))
+ }
+ case reflect.Float32:
+ if val, err := strconv.ParseFloat(defaultVal, 32); err == nil {
+ field.Set(reflect.ValueOf(float32(val)).Convert(field.Type()))
+ }
+ case reflect.Float64:
+ if val, err := strconv.ParseFloat(defaultVal, 64); err == nil {
+ field.Set(reflect.ValueOf(val).Convert(field.Type()))
+ }
+ case reflect.String:
+ field.Set(reflect.ValueOf(defaultVal).Convert(field.Type()))
+
+ case reflect.Slice:
+ ref := reflect.New(field.Type())
+ ref.Elem().Set(reflect.MakeSlice(field.Type(), 0, 0))
+ if defaultVal != "" && defaultVal != "[]" {
+ if err := json.Unmarshal([]byte(defaultVal), ref.Interface()); err != nil {
+ return err
+ }
+ }
+ field.Set(ref.Elem().Convert(field.Type()))
+ case reflect.Map:
+ ref := reflect.New(field.Type())
+ ref.Elem().Set(reflect.MakeMap(field.Type()))
+ if defaultVal != "" && defaultVal != "{}" {
+ if err := json.Unmarshal([]byte(defaultVal), ref.Interface()); err != nil {
+ return err
+ }
+ }
+ field.Set(ref.Elem().Convert(field.Type()))
+ case reflect.Struct:
+ if defaultVal != "" && defaultVal != "{}" {
+ if err := json.Unmarshal([]byte(defaultVal), field.Addr().Interface()); err != nil {
+ return err
+ }
+ }
+ case reflect.Ptr:
+ field.Set(reflect.New(field.Type().Elem()))
+ }
+ }
+
+ switch field.Kind() {
+ case reflect.Ptr:
+ if isInitial || field.Elem().Kind() == reflect.Struct {
+ setField(field.Elem(), defaultVal)
+ callSetter(field.Interface())
+ }
+ case reflect.Struct:
+ if err := Set(field.Addr().Interface()); err != nil {
+ return err
+ }
+ case reflect.Slice:
+ for j := 0; j < field.Len(); j++ {
+ if err := setField(field.Index(j), defaultVal); err != nil {
+ return err
+ }
+ }
+ case reflect.Map:
+ for _, e := range field.MapKeys() {
+ var v = field.MapIndex(e)
+
+ switch v.Kind() {
+ case reflect.Ptr:
+ switch v.Elem().Kind() {
+ case reflect.Struct, reflect.Slice, reflect.Map:
+ if err := setField(v.Elem(), ""); err != nil {
+ return err
+ }
+ }
+ case reflect.Struct, reflect.Slice, reflect.Map:
+ ref := reflect.New(v.Type())
+ ref.Elem().Set(v)
+ if err := setField(ref.Elem(), ""); err != nil {
+ return err
+ }
+ field.SetMapIndex(e, ref.Elem().Convert(v.Type()))
+ }
+ }
+ }
+
+ return nil
+}
+
+func isInitialValue(field reflect.Value) bool {
+ return reflect.DeepEqual(reflect.Zero(field.Type()).Interface(), field.Interface())
+}
+
+func shouldInitializeField(field reflect.Value, tag string) bool {
+ switch field.Kind() {
+ case reflect.Struct:
+ return true
+ case reflect.Ptr:
+ if !field.IsNil() && field.Elem().Kind() == reflect.Struct {
+ return true
+ }
+ case reflect.Slice:
+ return field.Len() > 0 || tag != ""
+ case reflect.Map:
+ return field.Len() > 0 || tag != ""
+ }
+
+ return tag != ""
+}
+
+// CanUpdate returns true when the given value is an initial value of its type
+func CanUpdate(v interface{}) bool {
+ return isInitialValue(reflect.ValueOf(v))
+}