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:
parent
3c806e6803
commit
c4ebd80669
15 changed files with 941 additions and 0 deletions
33
json.go
Normal file
33
json.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"git.juancwu.dev/juancwu/errx"
|
||||
)
|
||||
|
||||
// JSONFile loads a JSON object and exposes it as a flat key->string Source.
|
||||
func JSONFile(path string) (Source, error) {
|
||||
const op = "conf.JSONFile"
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, errx.Wrapf(op, err, "open %s", path)
|
||||
}
|
||||
defer f.Close()
|
||||
return JSONReader(f)
|
||||
}
|
||||
|
||||
// JSONReader is JSONFile for an arbitrary reader.
|
||||
func JSONReader(r io.Reader) (Source, error) {
|
||||
const op = "conf.JSONReader"
|
||||
var raw map[string]any
|
||||
if err := json.NewDecoder(r).Decode(&raw); err != nil {
|
||||
if err == io.EOF {
|
||||
return MapSource(nil), nil
|
||||
}
|
||||
return nil, errx.Wrap(op, err)
|
||||
}
|
||||
return MapSource(flatten(raw)), nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue