package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) type Config struct { Server ServerConfig `yaml:"server"` Database DatabaseConfig `yaml:"database"` BasicAuth BasicAuth `yaml:"basic_auth"` Homepage string `yaml:"homepage"` } func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { type rawConfig Config raw := rawConfig{ Server: ServerConfig{}, Database: DatabaseConfig{}, } if err := unmarshal(&raw); err != nil { return err } *c = Config(raw) return nil } type ServerConfig struct { ListeningPort string `yaml:"port"` TlsConfig TlsConfig `yaml:"tls"` } func (c *ServerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { type rawServerConfig ServerConfig raw := rawServerConfig{ TlsConfig: TlsConfig{}, } if err := unmarshal(&raw); err != nil { return err } *c = ServerConfig(raw) return nil } type DatabaseConfig struct { File string `yaml:"file"` LogMode bool `yaml:"log_mode"` MaxOpenConns int `yaml:"max_open_conns"` MaxIdleConns int `yaml:"max_idle_conns"` ConnMaxLifetime int `yaml:"conn_max_lifetime"` Pragma []string `yaml:"pragma"` } func (c *DatabaseConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { type rawDatabaseConfig DatabaseConfig raw := rawDatabaseConfig{} if err := unmarshal(&raw); err != nil { return err } if raw.File == "" { return fmt.Errorf("database file not provided") } *c = DatabaseConfig(raw) return nil } type TlsConfig struct { Enabled bool `yaml:"enabled"` CertFile string `yaml:"cert"` KeyFile string `yaml:"key"` } func (c *TlsConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { type rawTlsConfig TlsConfig raw := rawTlsConfig{ Enabled: false, } if err := unmarshal(&raw); err != nil { return err } if raw.Enabled && (raw.CertFile == "" || raw.KeyFile == "") { return fmt.Errorf("tls enabled but cert or key not provided") } *c = TlsConfig(raw) return nil } type BasicAuth struct { Username string `yaml:"username"` Password string `yaml:"password"` } func (c *BasicAuth) UnmarshalYAML(unmarshal func(interface{}) error) error { type rawBasicAuth BasicAuth raw := rawBasicAuth{} if err := unmarshal(&raw); err != nil { return err } if raw.Username == "" || raw.Password == "" { return fmt.Errorf("username or password not provided") } *c = BasicAuth(raw) return nil } func ReadConfig(cfgPath string) (*Config, error) { cfg, err := os.ReadFile(cfgPath) if err != nil { return nil, err } var config Config if err := yaml.Unmarshal(cfg, &config); err != nil { return nil, err } fmt.Println(config) return &config, nil }