diff options
Diffstat (limited to 'modules.go')
-rw-r--r-- | modules.go | 30 |
1 files changed, 30 insertions, 0 deletions
@@ -1,7 +1,9 @@ package caddy2 import ( + "encoding/json" "fmt" + "reflect" "sort" "strings" "sync" @@ -104,6 +106,34 @@ func Modules() []string { return names } +// LoadModule decodes rawMsg into a new instance of mod and +// returns the value. If mod.New() does not return a pointer +// value, it is converted to one so that it is unmarshaled +// into the underlying concrete type. If mod.New is nil, an +// error is returned. +func LoadModule(mod Module, rawMsg json.RawMessage) (interface{}, error) { + if mod.New == nil { + return nil, fmt.Errorf("no constructor") + } + + val, err := mod.New() + if err != nil { + return nil, fmt.Errorf("initializing module '%s': %v", mod.Name, err) + } + + // value must be a pointer for unmarshaling into concrete type + if rv := reflect.ValueOf(val); rv.Kind() != reflect.Ptr { + val = reflect.New(rv.Type()).Elem().Addr().Interface() + } + + err = json.Unmarshal(rawMsg, &val) + if err != nil { + return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err) + } + + return val, nil +} + var ( modules = make(map[string]Module) modulesMu sync.Mutex |