YAML Config Decoder
Decode YAML into typed structs with unknown-field rejection, then validate required addresses, durations, and size limits.
Code
package main
import (
"bytes"
"fmt"
"time"
"gopkg.in/yaml.v3"
)
type ServerConfig struct {
Addr string `yaml:"addr"`
ReadTimeout string `yaml:"read_timeout"`
MaxBodyBytes int64 `yaml:"max_body_bytes"`
}
type Config struct {
Server ServerConfig `yaml:"server"`
Features []string `yaml:"features"`
Debug bool `yaml:"debug"`
}
func LoadConfig(data []byte) (Config, error) {
var cfg Config
decoder := yaml.NewDecoder(bytes.NewReader(data))
decoder.KnownFields(true)
if err := decoder.Decode(&cfg); err != nil {
return Config{}, fmt.Errorf("decode config: %w", err)
}
if cfg.Server.Addr == "" {
return Config{}, fmt.Errorf("server.addr is required")
}
if _, err := time.ParseDuration(cfg.Server.ReadTimeout); err != nil {
return Config{}, fmt.Errorf("server.read_timeout: %w", err)
}
if cfg.Server.MaxBodyBytes <= 0 {
return Config{}, fmt.Errorf("server.max_body_bytes must be positive")
}
return cfg, nil
}
func main() {
document := []byte(`
server:
addr: ":8080"
read_timeout: 5s
max_body_bytes: 1048576
features:
- search
- preview
debug: false
`)
cfg, err := LoadConfig(document)
fmt.Printf("config: %+v err=%v\n", cfg, err)
unknown := []byte("server:\n addr: \":8080\"\n read_timeout: 5s\n max_body_bytes: 10\n tls: true\n")
_, err = LoadConfig(unknown)
fmt.Println("unknown field rejected:", err != nil)
}Report a problem with this exampleOpens a pre-filled issue on GitHub.