diff --git a/README.md b/README.md index 204ef22..7058ab9 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,10 @@ type MyConfig struct { cfg, err := config.Load[MyConfig]("my-service.toml", "MYSERVICE") +// Timeout fields use config.Duration (go-toml v2 doesn't decode +// strings to time.Duration natively). Access via .Duration: +readTimeout := cfg.Server.ReadTimeout.Duration // time.Duration + // Open database with standard pragmas and run migrations. database, err := db.Open(cfg.Database.Path) migrations := []db.Migration{ diff --git a/config/config.go b/config/config.go index 0fc8ea0..b28ff58 100644 --- a/config/config.go +++ b/config/config.go @@ -5,6 +5,24 @@ // the standard sections (Server, Database, MCIAS, Log). Use [Load] to // parse a TOML file, apply environment overrides, set defaults, and // validate required fields. +// +// # Duration fields +// +// Timeout fields in [ServerConfig] use the [Duration] type rather than +// [time.Duration] because go-toml v2 does not natively decode strings +// (e.g., "30s") into time.Duration. Access the underlying value via +// the embedded field: +// +// cfg.Server.ReadTimeout.Duration // time.Duration +// +// In TOML files, durations are written as Go duration strings: +// +// read_timeout = "30s" +// idle_timeout = "2m" +// +// Environment variable overrides also use this format: +// +// MCR_SERVER_READ_TIMEOUT=30s package config import ( diff --git a/config/duration.go b/config/duration.go index 71a99ac..24a400b 100644 --- a/config/duration.go +++ b/config/duration.go @@ -5,9 +5,18 @@ import ( "time" ) -// Duration is a time.Duration that can be unmarshalled from a TOML string +// Duration is a [time.Duration] that can be unmarshalled from a TOML string // (e.g., "30s", "5m"). go-toml v2 does not natively decode strings into -// time.Duration, so this wrapper implements encoding.TextUnmarshaler. +// time.Duration, so this wrapper implements [encoding.TextUnmarshaler]. +// +// Access the underlying time.Duration via the embedded field: +// +// cfg.Server.ReadTimeout.Duration // time.Duration value +// +// Duration values work directly with time functions that accept +// time.Duration because of the embedding: +// +// time.After(cfg.Server.ReadTimeout.Duration) type Duration struct { time.Duration }