Files
job-search/internal/config/config.go
T

101 lines
2.4 KiB
Go

package config
import (
"encoding/json"
"fmt"
"log/slog"
"reflect"
"strings"
"github.com/spf13/viper"
"go.yaml.in/yaml/v3"
)
const EnvPrefix string = "JOBSEARCH"
const EtcConfigPath string = "/etc/job-search"
// Each field's cfg tag must match the section's JSCK* constant.
type JobSearchConfig struct {
Logging JobSearchConfigLogging `cfg:"logging"`
Sources JobSearchConfigSources `cfg:"sources"`
}
// Default configuration, taken from the default struct tags
func LoadDefaultConfig() {
var conf JobSearchConfig
if err := applyDefaults(&conf); err != nil {
panic(fmt.Sprintf("config: %v", err))
}
LoadToViper(conf)
}
func (c JobSearchConfig) Map() map[string]any { return mapOf(c) }
func (c JobSearchConfig) Flatten() map[string]any { return flattenOf("", c) }
func (c JobSearchConfig) TypeOf(key string) (reflect.Kind, error) {
return typeOf(c, key)
}
func (c JobSearchConfig) ValueOf(key string) (any, error) {
return valueOf(c, key)
}
func (c *JobSearchConfig) SetValue(key string, value any) error {
return setValue(c, key, value)
}
// Utility method for loading a configuration from Viper
func LoadFromViper(conf *JobSearchConfig) {
keys := viper.AllKeys()
for idx := range keys {
key := keys[idx]
keyType, _ := conf.TypeOf(key)
if keyType == reflect.Invalid {
continue
}
switch keyType {
case reflect.String:
conf.SetValue(key, viper.GetString(key))
case reflect.Int:
conf.SetValue(key, viper.GetInt(key))
case reflect.Bool:
conf.SetValue(key, viper.GetBool(key))
default:
slog.Error(fmt.Sprintf("unknown key type: %s", keyType))
}
}
}
// Utility method for loading a configuration into Viper as defaults
func LoadToViper(conf JobSearchConfig) {
flatMap := conf.Flatten()
for key := range flatMap {
viper.SetDefault(key, flatMap[key])
}
}
// Converts configuration to a string in flat dotted format
func (conf JobSearchConfig) String() string {
var sb strings.Builder
for k, v := range conf.Flatten() {
typ, _ := conf.TypeOf(k)
sb.WriteString(fmt.Sprint(k, " = ", v, " <", typ, ">\n"))
}
return sb.String()
}
// Converts configuration to JSON
func (conf JobSearchConfig) JSON() string {
confMap := conf.Map()
jbytes, _ := json.MarshalIndent(confMap, "", " ")
return string(jbytes)
}
// Converts configuration to YAML
func (conf JobSearchConfig) YAML() string {
confMap := conf.Map()
ybytes, _ := yaml.Marshal(confMap)
return string(ybytes)
}