/* Copyright © 2026 Craig Williams This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ package config import ( "errors" "maps" "reflect" "strings" "github.com/spf13/viper" ) const EnvPrefix string = "JOBSEARCH" const EtcConfigPath string = "/etc/job-search" type JobSearchConfig struct { Logging JobSearchConfigLogging } // Default configuration func LoadDefaultConfig() { conf := JobSearchConfig{ Logging: defaultConfigLogging(), } LoadToViper(conf) } // Converts configuration to a map func (conf JobSearchConfig) Map() map[string]any { confMap := map[string]any{} confMap["logging"] = conf.Logging.Map() return confMap } // Converts configuration to a flat dotted format func (conf JobSearchConfig) Flatten() map[string]any { confFlat := map[string]any{} maps.Copy(confFlat, conf.Logging.Flatten()) return confFlat } // Returns the expected type of a configuration key value func (c JobSearchConfig) TypeOf(key string) (reflect.Kind, error) { keyParts := strings.Split(key, ".") switch keyParts[0] { case "logging": return c.Logging.TypeOf(strings.Join(keyParts[1:], ".")) default: return reflect.Invalid, errors.New("unknown configuration key") } } // Returns the expected type of a configuration value func (c JobSearchConfig) ValueOf(key string) (any, error) { keyParts := strings.Split(key, ".") switch keyParts[0] { case "logging": return c.Logging.ValueOf(strings.Join(keyParts[1:], ".")) default: return nil, errors.New("unknown configuration key") } } // Returns the expected type of a configuration value func (c *JobSearchConfig) SetValue(key string, value any) error { keyParts := strings.Split(key, ".") switch keyParts[0] { case "logging": return c.Logging.SetValue(strings.Join(keyParts[1:], "."), value) default: return errors.New("unknown configuration key") } } 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)) } } } func LoadToViper(conf JobSearchConfig) { flatMap := conf.Flatten() for key := range flatMap { viper.SetDefault(key, flatMap[key]) } }