Documentation ¶
Index ¶
- func CanonicalName(name string) string
- func Load(ctx context.Context, src Loader, inst interface{}) error
- func RenderENV(ctx context.Context, prefix string, inst interface{}) (string, error)
- func RenderYAML(ctx context.Context, inst interface{}) (string, error)
- func Walk(ctx context.Context, v Visitor, inst interface{}) error
- type Loader
- type LoaderMap
- type LoaderPrefixed
- type Path
- type PathSegment
- type PathSegmentInt
- type PathSegmentString
- type PathSegmentStringCanonical
- type Visit
- type Visitor
- type VisitorLoader
- func (vl *VisitorLoader) VisitMap(ctx context.Context, v Visit) error
- func (vl *VisitorLoader) VisitPrimitive(ctx context.Context, v Visit) error
- func (vl *VisitorLoader) VisitSlice(ctx context.Context, v Visit) error
- func (vl *VisitorLoader) VisitStruct(ctx context.Context, v Visit) error
- func (vl *VisitorLoader) VisitTime(ctx context.Context, v Visit) error
- type VisitorRenderENV
- func (vr *VisitorRenderENV) VisitMap(ctx context.Context, v Visit) error
- func (vr *VisitorRenderENV) VisitPrimitive(ctx context.Context, v Visit) error
- func (vr *VisitorRenderENV) VisitSlice(ctx context.Context, v Visit) error
- func (vr *VisitorRenderENV) VisitStruct(ctx context.Context, v Visit) error
- func (vr *VisitorRenderENV) VisitTime(ctx context.Context, v Visit) error
- type VisitorRenderYAML
- func (vr *VisitorRenderYAML) VisitMap(ctx context.Context, v Visit) error
- func (vr *VisitorRenderYAML) VisitPrimitive(ctx context.Context, v Visit) error
- func (vr *VisitorRenderYAML) VisitSlice(ctx context.Context, v Visit) error
- func (vr *VisitorRenderYAML) VisitStruct(ctx context.Context, v Visit) error
- func (vr *VisitorRenderYAML) VisitTime(ctx context.Context, v Visit) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CanonicalName ¶
CanonicalName converts a given field name into the canonical search path that will be used to look up a value in a Loader. The process of formatting a name is intended to match expectations of where a person might place an underscore if converting a word from CamelCase to snake_case. All canonical names are snake_case in order to maximize the human readability of the names in a configuration file. The following are example names and their conversions:
Value => value SomeValue => some_value DNSResolver => dns_resolver HTTPServerAddress => http_server_address HTTP2Enabled => http2_enabled HTTPV1Enabled => httpv1_enabled Http2ServerAddress => http2_server_address
The intended use case is converting Go struct field names into a friendly format. The expectation is that the field names are written using CamelCase in accordance with https://golang.org/doc/effective_go.html#mixed-caps.
The actual algorithm is based on several aspects of a string. Word detection is driven by the use of upper, lower, and digit characters. The following table defines the word selection:
Given l=lower case, U=upper case, 0=digit UU => continue word lU => complete word ending in l and start word beginning with U Ul => if last letter then continue word else if next letter is U then continue word else if word has more than one letter then complete word ending before U and start new word beginning with Ul else continue word ll => continue word l0 => continue word U0 => continue word 00 => continue word 0l => continue word 0U => complete word ending in 0 and start word beginning with U
func Load ¶ added in v0.2.0
Load is a utility method that creates a VisitorLoader and calls Walk using the given context, Loader, and configuration struct. This method can be used to populate a configuration struct with values.
func RenderENV ¶ added in v0.3.0
RenderENV is a utility function that renders an ENV representation of a configuration struct.
func RenderYAML ¶ added in v0.2.0
RenderYAML is a utility function that renders a YAML representation of a configuration struct.
func Walk ¶ added in v0.2.0
Walk traverses the instance fields in the order defined by reflect. Visitors should call this method with an instance of a struct if they need to recurse. Embedded fields are automically "rolled up" into the current instance so a Visitor.VisitStruct only needs to handle named fields that represent structs.
Types ¶
type Loader ¶
type Loader interface { // Load accepts a hierarchical path to a configuration value and returns the // raw form. The output must be interpreted by the caller in some way to // make it meaningful. The boolean value indicates whether or not the value // was found in the loader or if some default/nil value is returned. // Additionally, the error value can be non-nil if there was an exception // fetching data. // // Non-leaf values must be returned as either a map type or a slice type. Load(ctx context.Context, path Path) (interface{}, bool, error) }
Loader is any data source from which configuration values might be drawn.
type LoaderMap ¶ added in v0.2.0
type LoaderMap struct {
Map map[string]interface{}
}
LoaderMap is a Loader implementation backed by a static, in-memory map of arbitrary values. This may be re-used anywhere a source is static and can reasonably be converted into a tree structure of map[string]interface{}.
func NewLoaderEnv ¶ added in v0.3.0
NewLoaderEnv read environment variables into a map and uses those as configuration. There are some notable drawbacks to using this loader that include:
Most environments only support ASCII characters, numbers, and underscore characters which limits the possible variable names.
Array types have no official equivalent and must be implemented with a custom convention.
Map types have no official equivalent and must be implemented with a custom convention.
The same field canonicalization rules used by the other loaders are still used with this loader. The primary differences are the mechanism used to identify configuration data and the conventions used to separate heirachical structures. To start with, all environment variables that will be included in the lookup must start with a specific prefix. This prefix will be used by the loader to ensure it collects only relevant variables rather than all variables currently defined on the system.
The character set for environment variables is limited so we must choose a heirachical delimiter from the same character set used to encode variable names. The canonicalization rules will convert typical Go style into snake case using a single underscore. As a best effort for maintaining correctness, environment variables must use a double underscore, `__`, between variable names when identifying hierarchy. Some example of converting JSON objects in environment variables:
{"a": "b", "c": "d"} PREFIX__A=b PREFIX__C=d
{"a": {"b": ["c", "d", "e"]}} PREFIX__A__B__0=c PREFIX__A__B__1=d PREFIX__A__B__2=e
{"a": {"b": [{"c": "d"}, {"e":"f"}]}} PREFIX__A__B__0__C=d PREFIX__A__B__0__E=f
{"a": {"b": [{"c": ["d", "e"]}, {"f": ["g", "h"]}]}} PREFIX__A__B__0__C__0=d PREFIX__A__B__0__C__1=e PREFIX__A__B__1__F__0=g PREFIX__A__B__1__F__1=h
func NewLoaderFile ¶ added in v0.2.0
NewLoaderFile reads in the given file and parsing it with multiple encodings to find one that works. The path will be expanded if any ENV variables are encoded within such as /path/to/${VARIABLE}/location.
func NewLoaderJSON ¶ added in v0.2.0
NewLoaderJSON generates a config source from a JSON string.
func NewLoaderMap ¶ added in v0.2.0
NewLoaderMap is the recommended way to create a LoaderMap instance. While they can be created with any map[string]interface{}, this constructor ensures that all keys of the map have unicode normalization applied.
func NewLoaderYAML ¶ added in v0.2.0
NewLoaderYAML generates a config source from a YAML string.
type LoaderPrefixed ¶ added in v0.2.0
LoaderPrefixed is a wrapper for other Loader implementaions that adds one or more path segments to the front of every lookup.
type Path ¶ added in v0.2.0
type Path []PathSegment
Path is an ordered sequence of PathSegment values that are used to look up values in a Loader.
type PathSegment ¶ added in v0.2.0
type PathSegment interface { // Key returns the internal value if it is a string. If the internal value // is not a string then the boolean value returns as false. Key() (string, bool) // Offset returns the internal value if it is an integer. If the internal // value is not an integer then then boolean value returns false. Offset() (int, bool) }
PathSegment is a positional lookup element that is used as part of a full sequence to extract a value from a Loader. String path segments are considered key-based lookups and numeric segments are considered positional lookups. Positional lookups in this case are currently limited to offset positions of array/list/slice/etc. data structures. All other lookups should leverage the key-based lookups.
type PathSegmentInt ¶ added in v0.2.0
type PathSegmentInt int
PathSegmentInt implements PathSegment for offset based lookup values.
func (PathSegmentInt) Key ¶ added in v0.2.0
func (PathSegmentInt) Key() (string, bool)
Key always returns false.
func (PathSegmentInt) Offset ¶ added in v0.2.0
func (s PathSegmentInt) Offset() (int, bool)
Offset returns the internal value.
func (PathSegmentInt) String ¶ added in v0.2.0
func (s PathSegmentInt) String() string
type PathSegmentString ¶ added in v0.2.0
type PathSegmentString string
PathSegmentString implements PathSegment for string/key based lookup values.
func (PathSegmentString) Key ¶ added in v0.2.0
func (s PathSegmentString) Key() (string, bool)
Key returns the internal value.
func (PathSegmentString) Offset ¶ added in v0.2.0
func (PathSegmentString) Offset() (int, bool)
Offset always returns false.
func (PathSegmentString) String ¶ added in v0.2.0
func (s PathSegmentString) String() string
type PathSegmentStringCanonical ¶ added in v0.2.0
type PathSegmentStringCanonical string
PathSegmentStringCanonical implements PathSegment for string/Key based lookup values and applies canonicalization to the string value.
func (PathSegmentStringCanonical) Key ¶ added in v0.2.0
func (s PathSegmentStringCanonical) Key() (string, bool)
Key returns the internal value after applying canonicalization rules.
func (PathSegmentStringCanonical) Offset ¶ added in v0.2.0
func (PathSegmentStringCanonical) Offset() (int, bool)
Offset always returns false.
func (PathSegmentStringCanonical) String ¶ added in v0.2.0
func (s PathSegmentStringCanonical) String() string
type Visit ¶ added in v0.2.0
type Visit struct { // Name of the field that the visit represents. Name PathSegment // Tags includes any struct field annotations. Tags reflect.StructTag // Type is the reflect.Type of the resolved value. This value will never // be a pointer kind because pointers will be unrolled to the actual value // type. Type reflect.Type // Setter is a reflect.Value that represent the actual value of the field. // This type will match whatever type is recorded by Field. This is the // value that should be modified if any Value.Set() calls are made. Setter reflect.Value // Value is a reflect.Value that represents the resolved value of the field. // The type of this value will match the Type field. It may not be // addressable or settable under certain circumstances and can be the value // of `nil`. Value reflect.Value }
Visit is a data container that includes all relevant data known about a value given to a visitor.
type Visitor ¶ added in v0.2.0
type Visitor interface { VisitTime(ctx context.Context, v Visit) error VisitSlice(ctx context.Context, v Visit) error VisitMap(ctx context.Context, v Visit) error VisitStruct(ctx context.Context, v Visit) error VisitPrimitive(ctx context.Context, v Visit) error }
Visitor implementations are used in conjunction with Walk to process a configuration struct. The fields of the struct are processed in reflection order which is usually the order in which the fields are defined within the struct. Embedded types are unrolled depth-first. Any other struct types encountered are passed to VisitStruct. No recursive processing of struct types other than embedded types is performed unless the visitor makes an explicit call to Walk again. That is, visitors are responsible for engaging in recursive processing if they need to visit fields on a nested struct.
type VisitorLoader ¶ added in v0.2.0
type VisitorLoader struct {
Loader Loader
}
VisitorLoader is a Visitor implementation that populates a struct using a given Loader implementation.
func (*VisitorLoader) VisitMap ¶ added in v0.2.0
func (vl *VisitorLoader) VisitMap(ctx context.Context, v Visit) error
func (*VisitorLoader) VisitPrimitive ¶ added in v0.2.0
func (vl *VisitorLoader) VisitPrimitive(ctx context.Context, v Visit) error
VisitPrimitive loads standard language values with special support for time.Duration.
func (*VisitorLoader) VisitSlice ¶ added in v0.2.0
func (vl *VisitorLoader) VisitSlice(ctx context.Context, v Visit) error
VisitSlice iterates all found entries
func (*VisitorLoader) VisitStruct ¶ added in v0.2.0
func (vl *VisitorLoader) VisitStruct(ctx context.Context, v Visit) error
VisitStruct recursively processes a struct value by calling Walk with the current Visitor instance.
type VisitorRenderENV ¶ added in v0.3.0
VisitorRenderENV converts a struct into an environ slice. Optional values are included in the output as commented out fields.
func (*VisitorRenderENV) VisitMap ¶ added in v0.3.0
func (vr *VisitorRenderENV) VisitMap(ctx context.Context, v Visit) error
func (*VisitorRenderENV) VisitPrimitive ¶ added in v0.3.0
func (vr *VisitorRenderENV) VisitPrimitive(ctx context.Context, v Visit) error
func (*VisitorRenderENV) VisitSlice ¶ added in v0.3.0
func (vr *VisitorRenderENV) VisitSlice(ctx context.Context, v Visit) error
func (*VisitorRenderENV) VisitStruct ¶ added in v0.3.0
func (vr *VisitorRenderENV) VisitStruct(ctx context.Context, v Visit) error
type VisitorRenderYAML ¶ added in v0.2.0
VisitorRenderYAML converts a struct into a YAML document. Optional values are included in the output as commented out fields.
func (*VisitorRenderYAML) VisitMap ¶ added in v0.2.0
func (vr *VisitorRenderYAML) VisitMap(ctx context.Context, v Visit) error
func (*VisitorRenderYAML) VisitPrimitive ¶ added in v0.2.0
func (vr *VisitorRenderYAML) VisitPrimitive(ctx context.Context, v Visit) error
func (*VisitorRenderYAML) VisitSlice ¶ added in v0.2.0
func (vr *VisitorRenderYAML) VisitSlice(ctx context.Context, v Visit) error
func (*VisitorRenderYAML) VisitStruct ¶ added in v0.2.0
func (vr *VisitorRenderYAML) VisitStruct(ctx context.Context, v Visit) error