summaryrefslogtreecommitdiff
path: root/modules.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-03-26 15:45:51 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-03-26 15:45:51 -0600
commit86e2d1b0a48fbd84590291969611f1870471c3e0 (patch)
treed3a8d82ca88f7d7ff60476cd772d8c4314cd6a3f /modules.go
parent859b5d7ea3b8f660ac68d9aea5a53d25a9a7422c (diff)
Rudimentary start of HTTP servers
Diffstat (limited to 'modules.go')
-rw-r--r--modules.go30
1 files changed, 30 insertions, 0 deletions
diff --git a/modules.go b/modules.go
index 1c3e231..4a396d4 100644
--- a/modules.go
+++ b/modules.go
@@ -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