Documentation ¶
Overview ¶
Package cfg allows developers to define complex configuration for their applications with minimal code. This package has been designed to help satisfy the needs of teams who are building microservice in go. The goals of this package include:
- Allow teams to use consistent patterns for configuration across different applications.
- Coalesce multiple sources of configuration.
- Custom validation of configuration values.
- House a variety of tools to work with common configuration sources/formats.
Index ¶
Examples ¶
Constants ¶
const NoValueProvidedError sentinelError = "no value provided"
A NoValueProvidedError denotes that no value was provided.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type MultiProvider ¶ added in v0.0.4
MultiProvider allows a slice of Provider[T] to be used as a Provider[T].
func (MultiProvider[T]) Provide ¶ added in v0.0.4
func (m MultiProvider[T]) Provide(ctx context.Context) (T, error)
Provide iterates through each provider in m and returns the first value given by a provider. If a provider returns a NoValueProvidedError, the iteration continues. If no providers return a value, a NoValueProvidedError is returned.
type Provider ¶
A Provider loads a configuration value from a predetermined source. If no value is provided by the underlying source, the Provider must return a NoValueProvidedError.
Example (Custom) ¶
package main import ( "context" "fmt" "os" "github.com/zpatrick/cfg" ) type Environment string const ( Development Environment = "development" Staging Environment = "staging" Production Environment = "production" ) func main() { var env Environment schema := cfg.Schema[Environment]{ Dest: &env, Default: cfg.Addr(Development), Validator: cfg.OneOf(Development, Staging, Production), Provider: cfg.ProviderFunc[Environment](func(context.Context) (Environment, error) { appEnv := os.Getenv("APP_ENV") if appEnv == "" { return "", cfg.NoValueProvidedError } return Environment(appEnv), nil }), } os.Setenv("APP_ENV", "staging") if err := schema.Load(context.Background()); err != nil { panic(err) } fmt.Println(env) }
Output: staging
func StaticProvider ¶ added in v0.0.4
StaticProvider adapts v into a Provider[T]. If allowZero is false, the Provider will return a NoValueProvidedError if v is the zero value.
var p Provider[int] = StaticProvider(5)
func StaticProviderAddr ¶ added in v0.0.5
StaticProviderAddr adapts pv into a Provider[T]. If pv is nil, the Provider will return a NoValueProvidedError. If allowZero is false, the Provider will return a NoValueProvidedError if v is the zero value.
var p Provider[int] = StaticProviderAddr(&addr)
type ProviderFunc ¶
The ProviderFunc is an adapter type which allows ordinary functions to be used as Providers.
type Schema ¶ added in v0.0.4
type Schema[T any] struct { // Dest is a required field which points where to store the configuration value when Load is called. Dest *T // Provider is a required field which provides the configuration value. Provider Provider[T] // Default is an optional field which specifies the fallback value to use if Provider returns a NoValueProvidedError. Default *T // Validator is an optional field which ensures the value provided by Provider is valid. Validator Validator[T] }
A Schema models a configuration setting for an application.
Example (MultiProvider) ¶
package main import ( "context" "fmt" "os" "github.com/zpatrick/cfg" "github.com/zpatrick/cfg/envvar" ) func main() { var userName string schema := cfg.Schema[string]{ Dest: &userName, // Note that order matters when using MultiProvider: // We first will use USERNAME_ALPHA if that envvar is set, // falling back to using USERNAME_BRAVO if not. Provider: cfg.MultiProvider[string]{ envvar.New("USERNAME_ALPHA"), envvar.New("USERNAME_BRAVO"), }, } os.Setenv("USERNAME_ALPHA", "foo") os.Setenv("USERNAME_BRAVO", "bar") if err := schema.Load(context.Background()); err != nil { panic(err) } fmt.Println(userName) }
Output: foo
Example (Validation) ¶
package main import ( "context" "fmt" "github.com/zpatrick/cfg" ) func main() { var userName string schema := cfg.Schema[string]{ Dest: &userName, Validator: cfg.OneOf("admin", "guest"), Provider: cfg.StaticProvider("other", false), } if err := schema.Load(context.Background()); err != nil { fmt.Println(err) } }
Output: validation failed: input other not contained in [admin guest]
func (Schema[T]) Load ¶ added in v0.0.4
Load calls s.Provider.Provide to get the configuration value and store it into s.Dest. If s.Provider.Provide returns a NoValueProvidedError and s.Default is not nil, s.Default will be used instead. If s.Validator is set, it will be used to validate the provided value.
type Schemas ¶ added in v0.0.5
type Schemas map[string]interface { Load(context.Context) error // contains filtered or unexported methods }
Schemas is a named type for a map of Schemas.
type Validator ¶
type Validator[T any] interface { // Validate returns an error if input is considered invalid. Validate(input T) error }
A Validator checks whether or not a given value T is considered valid.
func And ¶
And combines the given validators into a single validator, requiring each validator check to succeed.
func Between ¶
func Between[T constraints.Ordered](min, max T) Validator[T]
Between returns a validator which ensures the input is >= min and <= max.
func OneOf ¶
func OneOf[T comparable](vals ...T) Validator[T]
OneOf returns a validator which ensures the input is equal to one of the given vals.
type ValidatorFunc ¶
A ValidatorFunc is an adapter type which allows functions to be used as Validators.
func (ValidatorFunc[T]) Validate ¶
func (f ValidatorFunc[T]) Validate(in T) error
Validate calls f(in).