package config import ( "errors" "log/slog" "os" "gopkg.in/yaml.v3" ) const ( LoggingOutputJson = "JSON" LoggingOutputText = "TEXT" ) type config struct { Credentials Credentials `yaml:"credentials"` Directory string `yaml:"directory"` WatchDebounceSeconds int `yaml:"watch_debounce_seconds"` LoggingConfig LoggingConfig `yaml:"logging" json:"logging"` } type LoggingConfig struct { Level string } func (lc LoggingConfig) ToLogger() *slog.Logger { var level slog.Level if err := level.UnmarshalText([]byte(lc.Level)); err != nil { level = slog.LevelInfo } leveler := new(slog.LevelVar) leveler.Set(level) return slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ Level: leveler, })) } type Credentials struct { SecretKey string `yaml:"secret_key"` TTDApiKey string `yaml:"ttd_api_key"` } type Config struct { Credentials Credentials Directory string WatchDebounceSeconds int Logger *slog.Logger } func LoadConfig(filePath string) (*Config, error) { // Set up slog as the main logger with default JSON handler logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) slog.SetDefault(logger) data, err := os.ReadFile(filePath) if err != nil { slog.Error("Failed to read configuration file", "error", err, "file", filePath) return nil, err } var cfg config if err := yaml.Unmarshal(data, &cfg); err != nil { slog.Error("Failed to unmarshal YAML configuration", "error", err) return nil, err } c := new(Config) c.Logger = cfg.LoggingConfig.ToLogger() if cfg.Credentials.SecretKey == "" || cfg.Credentials.TTDApiKey == "" { c.Logger.Error("Missing required credentials in configuration") return nil, errors.New("missing required credentials in configuration") } c.Credentials = cfg.Credentials c.Directory = cfg.Directory c.WatchDebounceSeconds = cfg.WatchDebounceSeconds // Log the selected provider data slog.Info("Successfully loaded configuration", "directory", c.Directory, "watch_debounce_seconds", c.WatchDebounceSeconds, ) return c, nil }