Files
codevault/internal/config/config.go

75 lines
2.0 KiB
Go

package config
import (
"errors"
"fmt"
"os"
"strings"
"go.uber.org/multierr"
"gopkg.in/yaml.v3"
)
var ErrLoggingDisabled error = errors.New("logging is disabled")
type Config struct {
Environment Environment `yaml:"environment"`
Server ServerConfig `yaml:"server"`
Database DatabaseConfig `yaml:"database"`
RateLimit RateLimitConfig `yaml:"rate_limit"`
Observability ObservabilityConfig `yaml:"observability"`
}
func (c *Config) Validate() error {
var err error
err = addValidationError(err, "environment validation error", c.Environment.PreprocessAndValidate())
err = addValidationError(err, "server section validation error", c.Server.Validate())
err = addValidationError(err, "database section validation error", c.Database.Validate())
err = addValidationError(err, "rate_limit section validation error", c.RateLimit.Validate())
err = addValidationError(err, "observability section validation error", c.Observability.Validate())
return err
}
func ReadConfig(path string) (Config, error) {
var c Config
yamlFile, err := os.ReadFile(path)
if err != nil {
return c, fmt.Errorf("could not read config: %w", err)
}
err = yaml.Unmarshal(yamlFile, &c)
if err != nil {
return c, fmt.Errorf("could not parse yaml: %w", err)
}
return c, nil
}
type Environment string
var (
ProductionEnvironment Environment = "production"
DevelopmentEnvironment Environment = "development"
)
func (e *Environment) PreprocessAndValidate() error {
preprocessed := strings.ToLower(string(*e))
switch preprocessed {
case string(ProductionEnvironment), "prod":
*e = ProductionEnvironment
return nil
case string(DevelopmentEnvironment), "dev":
*e = DevelopmentEnvironment
return nil
default:
return fmt.Errorf("invalid Environment value: '%v'", *e)
}
}
func addValidationError(err error, text string, validationError error) error {
if validationError == nil {
return err
}
return multierr.Append(err, fmt.Errorf("%s: %w", text, validationError))
}