New static configuration loading system.
Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
This commit is contained in:
parent
d18edd6f77
commit
8d7eccad5d
165 changed files with 10894 additions and 6076 deletions
97
pkg/config/generator/generator.go
Normal file
97
pkg/config/generator/generator.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Package generator implements the custom initialization of all the fields of an empty interface.
|
||||
package generator
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/containous/traefik/pkg/config/parser"
|
||||
)
|
||||
|
||||
type initializer interface {
|
||||
SetDefaults()
|
||||
}
|
||||
|
||||
// Generate recursively initializes an empty structure, calling SetDefaults on each field, when it applies.
|
||||
func Generate(element interface{}) {
|
||||
if element == nil {
|
||||
return
|
||||
}
|
||||
|
||||
generate(element)
|
||||
}
|
||||
|
||||
func generate(element interface{}) {
|
||||
field := reflect.ValueOf(element)
|
||||
|
||||
fill(field)
|
||||
}
|
||||
|
||||
func fill(field reflect.Value) {
|
||||
switch field.Kind() {
|
||||
case reflect.Ptr:
|
||||
setPtr(field)
|
||||
case reflect.Struct:
|
||||
setStruct(field)
|
||||
case reflect.Map:
|
||||
setMap(field)
|
||||
case reflect.Slice:
|
||||
if field.Type().Elem().Kind() == reflect.Struct ||
|
||||
field.Type().Elem().Kind() == reflect.Ptr && field.Type().Elem().Elem().Kind() == reflect.Struct {
|
||||
slice := reflect.MakeSlice(field.Type(), 1, 1)
|
||||
field.Set(slice)
|
||||
|
||||
// use Ptr to allow "SetDefaults"
|
||||
value := reflect.New(reflect.PtrTo(field.Type().Elem()))
|
||||
setPtr(value)
|
||||
|
||||
elem := value.Elem().Elem()
|
||||
field.Index(0).Set(elem)
|
||||
} else if field.Len() == 0 {
|
||||
slice := reflect.MakeSlice(field.Type(), 0, 0)
|
||||
field.Set(slice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setPtr(field reflect.Value) {
|
||||
if field.IsNil() {
|
||||
field.Set(reflect.New(field.Type().Elem()))
|
||||
}
|
||||
|
||||
if field.Type().Implements(reflect.TypeOf((*initializer)(nil)).Elem()) {
|
||||
method := field.MethodByName("SetDefaults")
|
||||
if method.IsValid() {
|
||||
method.Call([]reflect.Value{})
|
||||
}
|
||||
}
|
||||
|
||||
fill(field.Elem())
|
||||
}
|
||||
|
||||
func setStruct(field reflect.Value) {
|
||||
for i := 0; i < field.NumField(); i++ {
|
||||
fd := field.Field(i)
|
||||
structField := field.Type().Field(i)
|
||||
|
||||
if structField.Tag.Get(parser.TagLabel) == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
if parser.IsExported(structField) {
|
||||
fill(fd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setMap(field reflect.Value) {
|
||||
if field.IsNil() {
|
||||
field.Set(reflect.MakeMap(field.Type()))
|
||||
}
|
||||
|
||||
ptrValue := reflect.New(reflect.PtrTo(field.Type().Elem()))
|
||||
fill(ptrValue)
|
||||
|
||||
value := ptrValue.Elem().Elem()
|
||||
key := reflect.ValueOf(parser.MapNamePlaceholder)
|
||||
field.SetMapIndex(key, value)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue