config

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2019 License: MIT Imports: 4 Imported by: 0

README

config

A dynamic configuration library that allows for setting, retrieving, and removing arbitrary values referenced by keys.

Status

Build Status Coverage Status Go Report Card

Documentation and Usage

Full documentation and examples can be found at GoDoc

Documentation

Overview

Package config provides types that allow loading, storing, retrieving, and removing arbitrary values that are referenced by keys.

The Config Type

We can create instances of Config with New(). The zero valued &Config{} is not in a valid state and will likely cause panics if used. The New() func automatically sets Config's KeyParser to PeriodSeparatorKeyParser. This means that all string key parameters to Config methods will be converted to Key types in the manner of "a.b.c.d" -> Key([]string{"a", "b", "c", "d"}). A Config's KeyParser field can be changed before use to override this functionality.

Inserting values into a Config is simple and type agnostic. The Put*() methods all return whether or not the internal set of values changed.

c := New()
c.Put("foo", "bar") //true
c.Put("foo", "bar") //false
c.Put("foo", 1024)  //true

We can additionally use the Loader type to insert multiple values at once and from varying sources instead of calling individual Put*() methods.

type sliceLoader []interface{}

func (sl sliceLoader) Load() (*Values, error) {
	values := NewValues()
	for i, v := range sl {
		key := NewKey("slice", fmt.Sprint(i))
		values.Put(key, v)
	}
	return values, nil
}

loader := sliceLoader([]interface{}{"hello", "world", 234, true})
c := New()
c.MergeLoaders(loader) //true, nil

c.Get("slice.0") //hello
c.Get("slice.1") //world
c.Get("slice.2") //234
c.Get("slice.3") //true

See the Loader documentation and the loader subdirectory for information about pre-written loaders for common use cases.

The Values and Key Types

Type Values provides the actaul storage and retrieval of interface{} values. The values stored in a Values type are referenced by the Key type. Values is implemented as a tree with possible multiple children at each node. Each individual string in a Key is the "pointer" to the subtree of possibly more values.

For example:

//the following code...

v := NewValues()
v.Put(NewKey("a", "b"), 1)
v.Put(NewKey("a", "c"), 2)
v.Put(NewKey("d"), 3)

//results in this structure.
//       __root__
//       |      |
//       a      d
//       |      |
//    b--+--c   3
//    |     |
//    1     2

Continuing from this example, if we were to call v.Put(NewKey("a"), true), that would completely remove the [a b] -> 1 and [a c] -> 2 associations from v.

If we were to call v.Put(NewKey("a", "e"), "foobar"), that would result in the [a b] and [a c] associations remaining and the new [a e] -> "foobar" within v.

Index

Examples

Constants

View Source
const PeriodSeparatorKeyParser = SeparatorKeyParser(".")

PeriodSeparatorKeyParser is the default KeyParser set to c.KeyParser in New(). See SeparatorKeyParser.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	//KeyParser that turns strings into Keys that are then used with
	//this Config's underlying Values.
	//This enables easier access to Config's values with a simple string as opposed
	//to a Key type.
	KeyParser KeyParser
	// contains filtered or unexported fields
}

Config provides methods to store, retrieve, and remove arbitrary values that are referenced by keys.

The keys to a Config type are of type string. These string keys are parsed into Key types via a KeyParser. Key types that are parsed by a Config type are then used to reference into Values. Values is the storage type providing all functionality to Config.

Config is safe for use by multiple goroutines. Though the KeyParser is not protected from concurrent use, implementations can be implemented in a safe manner.

The zero value for *Config is not in a valid state and will likely cause panics if used.

func New

func New() *Config

New creates a new *Config with an empty Values and Loaders. KeyParser is set to PeriodSeparatorKeyParser.

func (*Config) AddLoaders

func (c *Config) AddLoaders(loaders ...Loader) *Config

AddLoaders adds Loaders to an internal slice of loaders. There is no check for duplicates or nil Loaders. This method servers as a utility to store Loaders associated with a Config to be merged into c at a later time by c.LoadAll().

func (*Config) Clone

func (c *Config) Clone() *Config

Clone creates and returns a new *Config with KeyParser and added loaders shallow copied, and with *Values cloned via *Values.Clone().

func (*Config) EqualValues

func (c *Config) EqualValues(other *Config) bool

EqualValues is sugar for c.Values().Equal(other.Values()).

func (*Config) Get

func (c *Config) Get(key string) (v interface{})

Get is sugar for c.GetKey(c.NewKey(key)). It returns a raw interface{} value stored at key or nil if a value does not exist at key.

func (*Config) GetBool

func (c *Config) GetBool(key string) (b bool)

GetBool returns a bool stored at key. The zero value for bool is returned if a bool does not exist at key.

func (*Config) GetBoolOk

func (c *Config) GetBoolOk(key string) (b bool, ok bool)

GetBoolOk returns a bool stored at key. The zero value for bool is returned if a bool does not exist at key. The return value ok indicates whether or not a bool actually exists at key.

func (*Config) GetFloat64

func (c *Config) GetFloat64(key string) (f float64)

GetFloat64 returns a float64 casted floating point type stored at key. The zero value for float64 is returned if a floating point type does not exist at key.

func (*Config) GetFloat64Ok

func (c *Config) GetFloat64Ok(key string) (f float64, ok bool)

GetFloat64Ok returns a float64 casted floating point type stored at key. The zero value for float64 is returned if a floating point type does not exist at key. The return value ok indicates whether or not a floating point type actually exists at key.

Example
c := New()

c.Put("float32", float32(1.5))
c.Put("float64", float64(2.5))
c.Put("int", int(2))

fmt.Println(c.GetFloat64Ok("float32"))
fmt.Println(c.GetFloat64Ok("float64"))
fmt.Println(c.GetFloat64Ok("int"))
fmt.Println(c.GetFloat64Ok("does not exist"))
Output:

1.5 true
2.5 true
0 false
0 false

func (*Config) GetInt64

func (c *Config) GetInt64(key string) (i int64)

GetInt64 returns an int64 casted integer type stored at key. The zero value for int64 is returned if an integer type does not exist at key.

func (*Config) GetInt64Ok

func (c *Config) GetInt64Ok(key string) (i int64, ok bool)

GetInt64Ok returns an int64 casted integer type stored at key. The zero value for int64 is returned if an integer type does not exist at key. The return value ok indicates whether or not an integer type actually exists at key.

Example
c := New()

c.Put("byte", byte(1))
c.Put("uint8", uint8(2))
c.Put("int8", int8(3))
c.Put("uint16", uint16(4))
c.Put("int16", int16(5))
c.Put("uint32", uint32(6))
c.Put("int32", int32(7))
c.Put("int", int(8))
c.Put("uint64", uint64(9))
c.Put("int64", int64(10))
c.Put("ooh", uint64(math.MaxUint64))
c.Put("string", "foobar")

fmt.Println(c.GetInt64Ok("byte"))
fmt.Println(c.GetInt64Ok("uint8"))
fmt.Println(c.GetInt64Ok("int8"))
fmt.Println(c.GetInt64Ok("uint16"))
fmt.Println(c.GetInt64Ok("int16"))
fmt.Println(c.GetInt64Ok("uint32"))
fmt.Println(c.GetInt64Ok("int32"))
fmt.Println(c.GetInt64Ok("int"))
fmt.Println(c.GetInt64Ok("uint64"))
fmt.Println(c.GetInt64Ok("int64"))
fmt.Println(c.GetInt64Ok("ooh"))
fmt.Println(c.GetInt64Ok("string"))
fmt.Println(c.GetInt64Ok("does not exist"))
Output:

1 true
2 true
3 true
4 true
5 true
6 true
7 true
8 true
9 true
10 true
-1 true
0 false
0 false

func (*Config) GetKey

func (c *Config) GetKey(key Key) (v interface{})

GetKey returns Get(key) called on c's internal *Values instance. It returns a raw interface{} value stored at key or nil if a value does not exist at key.

func (*Config) GetKeyOk

func (c *Config) GetKeyOk(key Key) (v interface{}, ok bool)

GetKeyOk returns GetKey(key) called on c's internal *Values instance. It returns a raw interface{} value stored at key or nil if a value does not exist at key. The return value ok indicates whether or not any value is actually stored at key.

func (*Config) GetOk

func (c *Config) GetOk(key string) (v interface{}, ok bool)

GetOk is sugar for c.GetKeyOk(c.NewKey(key)). It returns a raw interface{} value stored at key or nil if a value does not exist at key. The return value ok indicates whether or not any value is actually stored at key.

func (*Config) GetString

func (c *Config) GetString(key string) (s string)

GetString returns a string stored at key. The zero value for string is returned if a string does not exist at key.

func (*Config) GetStringOk

func (c *Config) GetStringOk(key string) (s string, ok bool)

GetStringOk returns a string stored at key. The zero value for string is returned if a string does not exist at key. The return value ok indicates whether or not a string actually exists at key.

func (*Config) GetValues

func (c *Config) GetValues(key string) (v *Values)

GetValues returns a *Values stored at key. This means that there exists some value stored at a longer Key. The returned *Values is cloned and thus changes to v DO NOT AFFECT c and vice versa. nil is returned if a *Values does not exist at key.

func (*Config) GetValuesOk

func (c *Config) GetValuesOk(key string) (v *Values, ok bool)

GetValuesOk returns a *Values stored at key. This means that there exists some value stored at a longer Key. The returned *Values is cloned and thus changes to v DO NOT AFFECT c and vice versa. nil is returned if more values do not exist at key. The return value ok indicates whether or not there are more values stored at key.

Example
c := New()

c.Put("a.b", 1)
c.Put("a.c", 2)
c.Put("d", 3)

printlnOk := func(key string) {
	_, ok := c.GetValuesOk(key)
	fmt.Println(ok)
}

printlnOk("a")
printlnOk("a.b")
printlnOk("a.c")
printlnOk("d")
printlnOk("does not exist")
Output:

true
false
false
false
false

func (*Config) LoadAll

func (c *Config) LoadAll() (bool, error)

LoadAll is a helper for c.MergeLoaders() called with all Loaders added previously with c.AddLoaders().

func (*Config) Merge

func (c *Config) Merge(other *Config) (changed bool)

Merge is sugar for c.Values().Merge(Key(nil), other.Values()).

func (*Config) MergeLoaders

func (c *Config) MergeLoaders(loaders ...Loader) (changed bool, err error)

MergeLoaders creates a temporary Values into which all Loaders in loaders are merged. If an error occurs on any individual Loader.Load(), then MergeLoaders returns immediately with that error and does not change c in any way. If all Loader.Load() do not error, then the temporary Values are merged into c's Values.

func (*Config) NewKey

func (c *Config) NewKey(k string) Key

NewKey returns the Key created by c.KeyParser.Parse(k).

func (*Config) Put

func (c *Config) Put(key string, value interface{}) (changed bool)

Put is sugar for c.PutKey(c.NewKey(key), value).

func (*Config) PutKey

func (c *Config) PutKey(key Key, value interface{}) (changed bool)

PutKey is sugar for c.Values().Put(key, value).

func (*Config) Remove

func (c *Config) Remove(key string) (value interface{}, ok bool)

Remove removes a Key value association in c's Values. It returns the value being removed. ok indicates whether or not a value was actually stored at key and was removed.

func (*Config) Values

func (c *Config) Values() *Values

Values returns the internal Values used for storage. The Values type is safe for use by multiple goroutines independent of the Config type. The internal reference is simply returned, and thus modifications to the returned *Values WILL AFFECT c.

type Key

type Key []string

Key is the entity that allows access to values stored within a Values instance.

func NewKey

func NewKey(parts ...string) Key

NewKey creates a Key with all strings in parts in the returned Key. It essentially casts the string slice to a Key.

func NewKeySep

func NewKeySep(source, sep string) Key

NewKeySep returns a Key that is the result of strings.Split(source, sep).

func (Key) Append

func (k Key) Append(others ...Key) Key

Append returns a new Key with all strings from k and other.

func (Key) AppendStrings

func (k Key) AppendStrings(others ...string) Key

AppendStrings returns a new Key with all strings from k and others.

func (Key) EndsWith

func (k Key) EndsWith(other Key) bool

EndsWith determines whether or not k is at least the same length as other and all strings in other appear at the last consecutive indices of k.

func (Key) Equal

func (k Key) Equal(other Key) bool

Equal determines whether or not k and other are the same length and all individual strings are identical at their respective indices.

func (Key) IsEmpty

func (k Key) IsEmpty() bool

IsEmpty determines whether or not the length of k is 0.

func (Key) Len

func (k Key) Len() int

Len returns the length of k.

func (Key) StartsWith

func (k Key) StartsWith(other Key) bool

StartsWith determines whether or not k is at least the same length as other and all strings in other appear at the first consecutive indices of k.

type KeyParser

type KeyParser interface {
	Parse(k string) Key
}

KeyParser defines an entity that can parse a string and turn it into a Key.

type KeyParserFunc

type KeyParserFunc func(k string) Key

KeyParserFunc is a func implementation of KeyParser that takes in a single string and returns a Key.

func (KeyParserFunc) Parse

func (pf KeyParserFunc) Parse(k string) Key

Parse simply calls pf(k).

type Loader

type Loader interface {
	Load() (*Values, error)
}

Loader defines an entity that can generate a new Values instance.

func NewFileFuncLoader

func NewFileFuncLoader(rfl ReaderFuncLoader, paths ...string) Loader

NewFileFuncLoader creates a Loader that uses rfl to load and merge Values from from each file existing at each path in paths. If rfl returns an error for any path in paths then that error is immediately returned from Loader.Load() and Values will be nil.

func NewReaderFuncLoader

func NewReaderFuncLoader(rfl ReaderFuncLoader, r io.Reader) Loader

NewReaderFuncLoader creates a Loader that return rfl(r) in its Load() method.

type ReaderFuncLoader

type ReaderFuncLoader func(io.Reader) (*Values, error)

ReaderFuncLoader is a func definition that takes in an io.Reader and returns a new Values instance and possible error.

type SeparatorKeyParser

type SeparatorKeyParser string

SeparatorKeyParser is a KeyParser that creates Keys from the result of calling strings.Split() with k and string(SeparatorKeyParser).

func (SeparatorKeyParser) Parse

func (p SeparatorKeyParser) Parse(k string) Key

Parse returns NewKeySep(k, string(p)).

type Values

type Values struct {
	// contains filtered or unexported fields
}

Values provides storage of arbitrary interface{} values referenced by type Key. The zero value for Values is not in a valid state, thus Values should be created with NewValues(). Values is safe for use by multiple goroutines.

func NewValues

func NewValues() *Values

NewValues creates an empty *Values.

func (*Values) Clone

func (v *Values) Clone() *Values

Clone creates a new Values with all associations copied into the result. The individual values are shallow copied into the result.

func (*Values) EachKeyValue

func (v *Values) EachKeyValue(visitor func(key Key, value interface{}))

EachKeyValue calls visitor with each set Key value association in v.

func (*Values) Equal

func (v *Values) Equal(other *Values) bool

Equal determines whether or not v and other contain the exact same set of Keys and associated values. Comparison on a value by value basis is done with the == operator.

func (*Values) Get

func (v *Values) Get(key Key) (value interface{})

Get returns the value associated with key or nil if the association does not exist.

func (*Values) GetOk

func (v *Values) GetOk(key Key) (value interface{}, ok bool)

GetOk return the value associated with key. The return value ok indicates whether or not any value is actually stored at key.

func (*Values) IsEmpty

func (v *Values) IsEmpty() bool

IsEmpty determines whether or not any associated exist in v.

func (*Values) Merge

func (v *Values) Merge(key Key, other *Values) bool

Merge merges all associations in other into v starting at key. To merge other in v at root, use an empty Key for key.

func (*Values) Put

func (v *Values) Put(key Key, value interface{}) (changed bool)

Put adds the key, value association to v. changed indicates whether or not this operation changes the set of associations in any way.

func (*Values) Remove

func (v *Values) Remove(key Key) (value interface{}, ok bool)

Remove deletes the association stored at key if one exists. v is the removed value or nil if nothing was returned, and ok indicated any value was actually removed.

Directories

Path Synopsis
loaders
env
Package env provides functions for easily creating a config.Loader that load values from the process environment.
Package env provides functions for easily creating a config.Loader that load values from the process environment.
flag
Package flag defines a config.Loader type that allows laoding values from command line arguments using the language's flag package.
Package flag defines a config.Loader type that allows laoding values from command line arguments using the language's flag package.
json
Package json provides a Loader type that can be used in conjunction with the parent config package to create a config.Loader to load values from JSON encoded objects.
Package json provides a Loader type that can be used in conjunction with the parent config package to create a config.Loader to load values from JSON encoded objects.

Jump to

Keyboard shortcuts

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