func EncodeStruct()

in backend/helpers/pluginhelper/api/config_util.go [98:169]


func EncodeStruct(input *viper.Viper, output interface{}, tag string) errors.Error {
	vf := reflect.ValueOf(output)
	if vf.Kind() != reflect.Ptr {
		return errors.Default.New(fmt.Sprintf("output %v is not a pointer", output))
	}

	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:
			vfField.SetString(input.GetString(fieldTag))
		case reflect.Int, reflect.Int64:
			vfField.SetInt(input.GetInt64(fieldTag))
		case reflect.Float64:
			vfField.SetFloat(input.GetFloat64(fieldTag))
		case reflect.Bool:
			vfField.SetBool(input.GetBool(fieldTag))
		case reflect.Slice:
			elem := vfField.Type().Elem()
			switch elem.Kind() {
			case reflect.String:
				value := input.GetStringSlice(fieldTag)
				stringSlice := reflect.MakeSlice(reflect.SliceOf(elem), 0, len(value))
				for _, item := range value {
					stringSlice = reflect.Append(stringSlice, reflect.ValueOf(item))
				}
				vfField.Set(stringSlice)
			case reflect.Int:
				value := input.GetIntSlice(fieldTag)
				intSlice := reflect.MakeSlice(reflect.SliceOf(elem), 0, len(value))
				for _, item := range value {
					intSlice = reflect.Append(intSlice, reflect.ValueOf(item))
				}
				vfField.Set(intSlice)
			}
		case reflect.Map:
			key := vfField.Type().Key()
			elem := vfField.Type().Elem()
			if key.Kind() == reflect.String {
				mapType := reflect.MapOf(key, elem)
				data := reflect.MakeMap(mapType)
				switch elem.Kind() {
				case reflect.String:
					for k, value := range input.GetStringMapString(fieldTag) {
						data.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(value))
					}
				case reflect.Interface:
					for k, value := range input.GetStringMap(fieldTag) {
						data.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(value))
					}
				}
				vfField.Set(data)
			}
		default:
		}
	}
	return nil
}