From bea0d22c26f8a912d2e20c4f88f92dcbe8f48b2e Mon Sep 17 00:00:00 2001 From: "antanst (aider)" Date: Mon, 11 Nov 2024 14:56:41 +0200 Subject: [PATCH] refactor: Replace switch statement with map-based config parsing --- config/config.go | 162 +++++++++++++++++++++++++++-------------------- 1 file changed, 92 insertions(+), 70 deletions(-) diff --git a/config/config.go b/config/config.go index 2e37f5d..aad1a08 100644 --- a/config/config.go +++ b/config/config.go @@ -8,83 +8,105 @@ import ( "github.com/rs/zerolog" ) +// Environment variable names +const ( + EnvLogLevel = "LOG_LEVEL" + EnvRootPath = "ROOT_PATH" + EnvNumWorkers = "NUM_OF_WORKERS" + EnvWorkerBatchSize = "WORKER_BATCH_SIZE" + EnvMaxResponseSize = "MAX_RESPONSE_SIZE" + EnvResponseTimeout = "RESPONSE_TIMEOUT" +) + +// Config holds the application configuration loaded from environment variables type Config struct { - LogLevel zerolog.Level - rootPath string - MaxResponseSize int - NumOfWorkers int - ResponseTimeout int - WorkerBatchSize int + LogLevel zerolog.Level // Logging level (debug, info, warn, error) + RootPath string // Root path for the application + MaxResponseSize int // Maximum size of response in bytes + NumOfWorkers int // Number of concurrent workers + ResponseTimeout int // Timeout for responses in seconds + WorkerBatchSize int // Batch size for worker processing } var CONFIG Config +// parsePositiveInt parses and validates positive integer values +func parsePositiveInt(value string) (int, error) { + val, err := strconv.Atoi(value) + if err != nil { + return 0, err + } + if val <= 0 { + return 0, fmt.Errorf("value must be positive") + } + return val, nil +} + +// GetConfig loads and validates configuration from environment variables func GetConfig() *Config { - var config Config - for _, envVar := range []string{ - "LOG_LEVEL", - "ROOT_PATH", - "NUM_OF_WORKERS", - "WORKER_BATCH_SIZE", - "MAX_RESPONSE_SIZE", - "RESPONSE_TIMEOUT", - } { - if env, ok := os.LookupEnv(envVar); !ok { - fmt.Fprintf(os.Stderr, "Missing env var %s\n", envVar) - os.Exit(1) - } else { - switch envVar { - case "LOG_LEVEL": - { - logLevel, err := zerolog.ParseLevel(env) - if err != nil { - fmt.Fprintf(os.Stderr, "Invalid LOG_LEVEL value\n") - os.Exit(1) - } - config.LogLevel = logLevel - } - case "ROOT_PATH": - { - config.rootPath = env - } - case "NUM_OF_WORKERS": - { - if numOfWorkers, err := strconv.Atoi(env); err != nil { - fmt.Fprintf(os.Stderr, "Invalid NUM_OF_WORKERS value\n") - os.Exit(1) - } else { - config.NumOfWorkers = numOfWorkers - } - } - case "WORKER_BATCH_SIZE": - { - if workerBatchSize, err := strconv.Atoi(env); err != nil { - fmt.Fprintf(os.Stderr, "Invalid WORKER_BATCH_SIZE value\n") - os.Exit(1) - } else { - config.WorkerBatchSize = workerBatchSize - } - } - case "MAX_RESPONSE_SIZE": - { - if maxResponseSize, err := strconv.Atoi(env); err != nil { - fmt.Fprintf(os.Stderr, "Invalid MAX_RESPONSE_SIZE value\n") - os.Exit(1) - } else { - config.MaxResponseSize = maxResponseSize - } - } - case "RESPONSE_TIMEOUT": - { - if val, err := strconv.Atoi(env); err != nil { - fmt.Fprintf(os.Stderr, "Invalid RESPONSE_TIMEOUT value\n") - os.Exit(1) - } else { - config.ResponseTimeout = val - } - } + config := &Config{} + + // Map of environment variables to their parsing functions + parsers := map[string]func(string) error{ + EnvLogLevel: func(v string) error { + level, err := zerolog.ParseLevel(v) + if err != nil { + return fmt.Errorf("invalid log level: %w", err) } + config.LogLevel = level + return nil + }, + EnvRootPath: func(v string) error { + config.RootPath = v + return nil + }, + EnvNumWorkers: func(v string) error { + val, err := parsePositiveInt(v) + if err != nil { + return fmt.Errorf("invalid number of workers: %w", err) + } + config.NumOfWorkers = val + return nil + }, + EnvWorkerBatchSize: func(v string) error { + val, err := parsePositiveInt(v) + if err != nil { + return fmt.Errorf("invalid worker batch size: %w", err) + } + config.WorkerBatchSize = val + return nil + }, + EnvMaxResponseSize: func(v string) error { + val, err := parsePositiveInt(v) + if err != nil { + return fmt.Errorf("invalid max response size: %w", err) + } + config.MaxResponseSize = val + return nil + }, + EnvResponseTimeout: func(v string) error { + val, err := parsePositiveInt(v) + if err != nil { + return fmt.Errorf("invalid response timeout: %w", err) + } + config.ResponseTimeout = val + return nil + }, + } + + // Process each environment variable + for envVar, parser := range parsers { + value, ok := os.LookupEnv(envVar) + if !ok { + fmt.Fprintf(os.Stderr, "Missing required environment variable: %s\n", envVar) + os.Exit(1) + } + + if err := parser(value); err != nil { + fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err) + os.Exit(1) } } - return &config + + return config }