cfg

package module
v0.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2024 License: MIT Imports: 6 Imported by: 0

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

View Source
const NoValueProvidedError sentinelError = "no value provided"

A NoValueProvidedError denotes that no value was provided.

Variables

This section is empty.

Functions

func Addr added in v0.0.4

func Addr[T any](t T) *T

Addr returns the address of t.

func Load added in v0.0.4

func Load(ctx context.Context, schemas Schemas) error

Load calls Load(ctx) for each schema in schemas.

Types

type MultiProvider added in v0.0.4

type MultiProvider[T any] []Provider[T]

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

type Provider[T any] interface {
	Provide(ctx context.Context) (T, error)
}

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

func StaticProvider[T any](v T, allowZero bool) Provider[T]

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

func StaticProviderAddr[T any](pv *T, allowZero bool) Provider[T]

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

type ProviderFunc[T any] func(ctx context.Context) (T, error)

The ProviderFunc is an adapter type which allows ordinary functions to be used as Providers.

func (ProviderFunc[T]) Provide

func (f ProviderFunc[T]) Provide(ctx context.Context) (T, error)

Provide calls f(ctx).

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

func (s Schema[T]) Load(ctx context.Context) error

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

func And[T any](a, b Validator[T], vs ...Validator[T]) Validator[T]

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 Not added in v0.0.4

func Not[T any](v Validator[T]) Validator[T]

Not returns a new validator which throws an error when v does not.

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.

func Or

func Or[T any](a, b Validator[T], vs ...Validator[T]) Validator[T]

Or combines the given validators into a single validator, requiring only one validator check to succeed.

type ValidatorFunc

type ValidatorFunc[T any] func(T) error

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).

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL