LoadEnv config loader with defaults and validation

Go
package config

import (
    "fmt"
    "os"
    "strconv"
    "time"
)

// Config holds the service settings read from the environment.
type Config struct {
    Addr    string
    Workers int
    Timeout time.Duration
}

// LoadEnv reads APP_* variables, applies defaults, and rejects bad values.
func LoadEnv() (*Config, error) {
    cfg := &Config{Addr: envOr("APP_ADDR", ":8080")}
    workers, err := strconv.Atoi(envOr("APP_WORKERS", "4"))
    if err != nil || workers < 1 {
        return nil, fmt.Errorf("APP_WORKERS: want a positive int, got %q", os.Getenv("APP_WORKERS"))
    }
    cfg.Workers = workers
    timeout, err := time.ParseDuration(envOr("APP_TIMEOUT", "5s"))
    if err != nil || timeout <= 0 {
        return nil, fmt.Errorf("APP_TIMEOUT: want a positive duration, got %q", os.Getenv("APP_TIMEOUT"))
    }
    cfg.Timeout = timeout
    return cfg, nil
}

func envOr(key, fallback string) string {
    if v := os.Getenv(key); v != "" {
        return v
    }
    return fallback
}