func DecodeStruct()

in backend/helpers/pluginhelper/api/config_util.go [33:93]


func DecodeStruct(output *viper.Viper, input interface{}, data map[string]interface{}, tag string) errors.Error {
	// update fields from request body
	err := Decode(data, input, validator.New())
	if err != nil {
		return err
	}

	vf := reflect.ValueOf(input)
	if vf.Kind() != reflect.Ptr {
		return errors.Default.New(fmt.Sprintf("input %v is not a pointer", input))
	}

	for _, f := range utils.WalkFields(reflect.Indirect(vf).Type(), nil) {
		fieldName := f.Name
		fieldType := f.Type
		fieldTag := f.Tag.Get(tag)

		// Check if the first letter is uppercase (indicates a public element, accessible)
		ascii := rune(fieldName[0])
		if int(ascii) < int('A') || int(ascii) > int('Z') {
			continue
		}

		// View their tags in order to filter out members who don't have a valid tag set
		if fieldTag == "" {
			continue
		}
		vfField := vf.Elem().FieldByName(fieldName)
		switch fieldType.Kind() {
		case reflect.String:
			output.Set(fieldTag, vfField.String())
		case reflect.Int, reflect.Int64:
			output.Set(fieldTag, vfField.Int())
		case reflect.Float64, reflect.Float32:
			output.Set(fieldTag, vfField.Float())
		case reflect.Bool:
			output.Set(fieldTag, vfField.Bool())
		case reflect.Slice:
			elemType := vfField.Type().Elem().Kind()
			switch elemType {
			case reflect.String:
				output.Set(fieldTag, vfField.Interface().([]string))
			case reflect.Int:
				output.Set(fieldTag, vfField.Interface().([]int))
			}
		case reflect.Map:
			keyType := vfField.Type().Key().Kind()
			elemType := vfField.Type().Elem().Kind()
			if keyType == reflect.String {
				switch elemType {
				case reflect.String:
					output.Set(fieldTag, vfField.Interface().(map[string]string))
				case reflect.Interface:
					output.Set(fieldTag, vfField.Interface().(map[string]interface{}))
				}
			}
		default:
		}
	}
	return nil
}