Documentation
¶
Overview ¶
Package config provides a generic, application-agnostic configuration overlay system with named layers and a repository pattern.
The core concept is that configuration comes from multiple sources (defaults, files, CLI flags, etc.) organized as named layers from least-specific to most-specific. The repository computes the effective configuration by overlaying layers on demand.
Index ¶
- func Overlay[T any](base T, layers ...T) T
- func OverlayMaps(layers ...map[string]any) map[string]any
- type LayerValue
- type MapStore
- func (r *MapStore) Clear(layer string)
- func (r *MapStore) ClearField(key string)
- func (r *MapStore) ClearLayerField(layer, key string)
- func (r *MapStore) Get() map[string]any
- func (r *MapStore) GetField(key string) (any, bool)
- func (r *MapStore) GetLayer(layer string) (map[string]any, bool)
- func (r *MapStore) GetLayerField(layer, key string) (any, bool)
- func (r *MapStore) Has(layer string) bool
- func (r *MapStore) Inspect(key string) []LayerValue
- func (r *MapStore) Set(layer string, value map[string]any) error
- func (r *MapStore) SetField(layer, key string, value any)
- type Store
- func (r *Store[T]) Clear(layer string)
- func (r *Store[T]) ClearField(field string) error
- func (r *Store[T]) ClearLayerField(layer, field string) error
- func (r *Store[T]) Get() T
- func (r *Store[T]) GetField(field string) (any, error)
- func (r *Store[T]) GetLayer(layer string) (T, bool)
- func (r *Store[T]) GetLayerField(layer, field string) (any, bool)
- func (r *Store[T]) Has(layer string) bool
- func (r *Store[T]) Inspect(field string) []LayerValue
- func (r *Store[T]) Set(layer string, value T) error
- func (r *Store[T]) SetField(layer, field string, value any) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Overlay ¶
func Overlay[T any](base T, layers ...T) T
Overlay merges struct layers from least-specific to most-specific.
The base argument serves as the template and provides default values. Each subsequent layer can override fields. For each field, the most-specific (last) defined value wins.
A field is "defined" based on its type:
- Pointer fields: defined when non-nil (nil = unset)
- Non-pointer fields: always defined (zero values participate in overlay)
- Slices: defined when non-nil
- Maps: defined when non-nil
- Nested structs: defined when any child field is defined
Use pointer fields when the zero value is a valid setting and you need to distinguish "not set" from "set to zero".
func OverlayMaps ¶
OverlayMaps merges map layers from least-specific to most-specific.
Unlike Overlay for structs, map overlay uses the union of all keys across all layers. For each key, the most-specific (last) layer wins.
Nested maps (map[string]any values) are overlayed recursively — inner maps are merged, not replaced wholesale.
Slice values are NOT merged — the most-specific layer's slice replaces the less-specific one entirely.
Types ¶
type LayerValue ¶
type LayerValue struct {
Layer string // Layer name (e.g., "default", "file", "cli args")
Value any // The field's value at this layer
Defined bool // Whether the field is defined (set) at this layer
}
LayerValue represents a field's value at a specific layer. Used by Inspect to show the full resolution chain for diagnostics.
type MapStore ¶
type MapStore struct {
// contains filtered or unexported fields
}
MapStore holds ordered named layers of map[string]any and computes the effective configuration by overlaying them on demand.
Unlike Store[T], MapStore works with dynamic key sets. Keys from any layer are included in the result (union). Nested maps are overlayed recursively.
All methods are safe for concurrent use.
func NewMapStore ¶
NewMapStore creates a map repository with the given layer names, ordered from least-specific to most-specific.
repo := NewMapStore("daemon", "group", "trigger")
func (*MapStore) Clear ¶
Clear removes a layer's map entirely (resets to unset). Invalidates the cache.
func (*MapStore) ClearField ¶
ClearField removes a key from ALL layers. Invalidates the cache.
func (*MapStore) ClearLayerField ¶
ClearLayerField removes a single key from a specific layer's map. Invalidates the cache.
func (*MapStore) Get ¶
Get computes and returns the effective configuration by overlaying all defined layers in order. Nested maps are merged recursively. The result is cached until the next mutation.
func (*MapStore) GetField ¶
GetField returns the effective value for a single key. Uses the cache if available, recomputes if stale.
func (*MapStore) GetLayer ¶
GetLayer returns the raw map stored at a specific layer. Returns false if the layer has not been set.
func (*MapStore) GetLayerField ¶
GetLayerField returns a single key's value at a specific layer. Returns false if the layer is unset or the key is absent.
func (*MapStore) Inspect ¶
func (r *MapStore) Inspect(key string) []LayerValue
Inspect returns the value of a key across all layers, ordered from most-specific to least-specific (base layer last).
type Store ¶
type Store[T any] struct { // contains filtered or unexported fields }
Store holds ordered named layers of type T and computes the effective configuration by overlaying them on demand.
Layers are ordered from least-specific to most-specific, as declared in NewStore. The effective value is computed fresh on Get() or served from cache if no mutations have occurred.
All methods are safe for concurrent use.
func NewStore ¶
NewStore creates a repository with the given layer names, ordered from least-specific to most-specific.
repo := NewStore[AppConfig]("default", "file", "cli")
func (*Store[T]) Clear ¶
Clear removes a layer's value entirely (resets to unset). Invalidates the cache.
func (*Store[T]) ClearField ¶
ClearField clears a field across ALL layers (resets to undefined in every layer). Returns an error for unknown field names. Invalidates the cache.
func (*Store[T]) ClearLayerField ¶
ClearLayerField clears a single field in a specific layer (resets to undefined). Returns an error for unknown field or layer names. Invalidates the cache.
func (*Store[T]) Get ¶
func (r *Store[T]) Get() T
Get computes and returns the effective configuration by overlaying all defined layers in order. The result is cached until the next mutation (Set, SetField, Clear, ClearField, ClearLayerField).
func (*Store[T]) GetField ¶
GetField computes and returns the effective value of a single field. Uses the cache if available, recomputes if stale. Returns an error for unknown field names.
func (*Store[T]) GetLayer ¶
GetLayer returns the raw value stored at a specific layer. Returns false if the layer has not been set.
func (*Store[T]) GetLayerField ¶
GetLayerField returns a single field's value at a specific layer. Returns false if the layer is unset or the field is undefined in that layer.
func (*Store[T]) Inspect ¶
func (r *Store[T]) Inspect(field string) []LayerValue
Inspect returns the value of a field across all layers, ordered from most-specific to least-specific (base layer last). Each entry shows the layer name, the value, and whether the field is defined at that layer.
func (*Store[T]) Set ¶
Set stores an entire value for a layer. Returns an error for unknown layer names. Invalidates the cache.