package config import ( "errors" "fmt" "reflect" "strconv" "github.com/spf13/viper" ) // StoreValue parses value as the type of key, checks conf accepts it, sets it // in conf and Viper and writes the config file Viper is using. It returns the // parsed value and its kind. func StoreValue( conf *JobSearchConfig, key string, value string, ) (any, reflect.Kind, error) { var confValue any = nil var confType reflect.Kind var err error confType, err = conf.TypeOf(key) if err != nil { return nil, confType, err } switch confType { case reflect.Bool: confValue, err = strconv.ParseBool(value) case reflect.String: confValue = value case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: confValue, err = strconv.ParseInt(value, 10, 64) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: confValue, err = strconv.ParseUint(value, 10, 64) case reflect.Float32, reflect.Float64: confValue, err = strconv.ParseFloat(value, 64) default: err = errors.ErrUnsupported } if err != nil { return nil, confType, fmt.Errorf( "config value type not accepted, expected <%s>", confType, ) } // Reject values the configuration itself would not accept, e.g. an // unknown log level or an unparseable duration. if err := conf.SetValue(key, confValue); err != nil { return nil, confType, err } viper.Set(key, confValue) if err := viper.WriteConfig(); err != nil { return nil, confType, err } return confValue, confType, nil } // PurgeValue rewrites the config file Viper is using without key. func PurgeValue(conf *JobSearchConfig, key string) error { if _, err := conf.TypeOf(key); err != nil { return err } v := viper.New() v.SetConfigFile(viper.ConfigFileUsed()) keys := viper.AllKeys() for i := range keys { k := keys[i] if k != key { v.Set(k, viper.Get(k)) } } if err := v.WriteConfig(); err != nil { return err } return nil }