Files
conf/settings.go

110 lines
3.0 KiB
Go
Raw Normal View History

2021-03-20 21:10:53 +03:00
package conf
import (
"errors"
"strconv"
"strings"
)
var (
2025-04-09 02:13:47 +03:00
ErrNotFound = errors.New("conf: key not found")
ErrCouldNotConvert = errors.New("conf: could not cast one or more values to required type")
2021-03-20 21:10:53 +03:00
)
2025-04-09 02:13:47 +03:00
const valuesSeparator = ","
2021-03-20 21:10:53 +03:00
// Setting represents key-value pair read from config file.
// It's Value field holds the value of key parsed from the configuration
type Setting struct {
2025-04-09 02:13:47 +03:00
Name string
2021-03-20 21:10:53 +03:00
Value string
}
// Int converts Setting Value to int. Returned error
// will be non nil if convesion failed.
2025-04-09 02:13:47 +03:00
func (s Setting) Int() (int, error) {
return parseValue(s.Value, strconv.Atoi)
2021-03-20 21:10:53 +03:00
}
// IntSlice splits Setting Value (separator is ",") and adds
// each of resulting values to []int if possible.
// If one or more values can not be converted to float64 those will be dropped
// and method will return conf.ErrCouldNotConvert.
// Check error to be sure that all required values were parsed.
2025-04-09 02:13:47 +03:00
func (s Setting) IntSlice() ([]int, error) {
return parseSlice(s.Value, strconv.Atoi)
2021-03-20 21:10:53 +03:00
}
// Float64 converts Setting Value to float64. Returned error
// will be non nil if convesion failed.
2025-04-09 02:13:47 +03:00
func (s Setting) Float64() (float64, error) {
return parseValue(s.Value, parseFloat64)
2021-03-20 21:10:53 +03:00
}
// Float64Slice splits Setting Value (separator is ",") and adds
// each of resulting values to []float64 if possible.
// If one or more values can not be converted to float64 those will be dropped
// and method will return conf.ErrCouldNotConvert.
// Check error to be sure that all required values were parsed.
2025-04-09 02:13:47 +03:00
func (s Setting) Float64Slice() ([]float64, error) {
return parseSlice(s.Value, parseFloat64)
2021-03-20 21:10:53 +03:00
}
// String returns option Value as string
// This method also implements Stringer interface from fmt module
2025-04-09 02:13:47 +03:00
func (s Setting) String() string {
return s.Value
2021-03-20 21:10:53 +03:00
}
// StringSlice splits Setting's Value (separator is ",") and adds
// each of resulting values to []string trimming leading and trailing spaces
// from each string.
2025-04-09 02:13:47 +03:00
func (s Setting) StringSlice() []string {
return tidySplit(s.Value)
2021-03-20 21:10:53 +03:00
}
// Bool tries to interpret Setting's Value as bool
2025-04-09 02:13:47 +03:00
// "1", "t", "T", true", "True", "TRUE" yields true
// "0", "f", "F, "false", "False", "FALSE" yields false
// If nothing matches will return false and conf.ErrCouldNotConvert.
func (s Setting) Bool() (bool, error) {
return parseValue(s.Value, strconv.ParseBool)
2021-03-20 21:10:53 +03:00
}
2025-04-09 02:13:47 +03:00
func parseSlice[T any](s string, f func(string) (T, error)) ([]T, error) {
split := tidySplit(s)
2021-03-20 21:10:53 +03:00
2025-04-09 02:13:47 +03:00
list := make([]T, 0, len(split))
for _, str := range split {
v, err := parseValue(str, f)
2021-03-20 21:10:53 +03:00
if err != nil {
2025-04-09 02:13:47 +03:00
return list, err
2021-03-20 21:10:53 +03:00
}
2025-04-09 02:13:47 +03:00
list = append(list, v)
2021-03-20 21:10:53 +03:00
}
2025-04-09 02:13:47 +03:00
return list, nil
2021-03-20 21:10:53 +03:00
}
2025-04-09 02:13:47 +03:00
func parseValue[T any](s string, f func(string) (T, error)) (T, error) {
v, err := f(s)
if err != nil {
return v, errors.Join(ErrCouldNotConvert, err)
2021-03-20 21:10:53 +03:00
}
2025-04-09 02:13:47 +03:00
return v, err
2021-03-20 21:10:53 +03:00
}
2025-04-09 02:13:47 +03:00
func tidySplit(s string) []string {
splitted := strings.Split(s, valuesSeparator)
2021-03-20 21:10:53 +03:00
for i, str := range splitted {
2025-04-09 02:13:47 +03:00
splitted[i] = strings.TrimSpace(str)
2021-03-20 21:10:53 +03:00
}
return splitted
}
2025-04-09 02:13:47 +03:00
func parseFloat64(s string) (float64, error) {
return strconv.ParseFloat(s, 64)
}