Add reflective struct-tag config loader

Implements conf.Load to populate tagged structs from a chain of Sources
(env, .env, YAML/JSON/TOML, custom). Supports default values, slice
separators, nested structs, pointer fields, and a Validator hook.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
juancwu 2026-04-27 20:35:51 +00:00
commit c4ebd80669
15 changed files with 941 additions and 0 deletions

30
toml.go Normal file
View file

@ -0,0 +1,30 @@
package conf
import (
"io"
"os"
"git.juancwu.dev/juancwu/errx"
"github.com/BurntSushi/toml"
)
// TOMLFile loads a TOML document and exposes it as a flat key->string Source.
func TOMLFile(path string) (Source, error) {
const op = "conf.TOMLFile"
f, err := os.Open(path)
if err != nil {
return nil, errx.Wrapf(op, err, "open %s", path)
}
defer f.Close()
return TOMLReader(f)
}
// TOMLReader is TOMLFile for an arbitrary reader.
func TOMLReader(r io.Reader) (Source, error) {
const op = "conf.TOMLReader"
var raw map[string]any
if _, err := toml.NewDecoder(r).Decode(&raw); err != nil {
return nil, errx.Wrap(op, err)
}
return MapSource(flatten(raw)), nil
}