MCPcopy
hub / github.com/caddyserver/caddy / LoadModule

Method LoadModule

context.go:188–287  ·  view source on GitHub ↗

LoadModule loads the Caddy module(s) from the specified field of the parent struct pointer and returns the loaded module(s). The struct pointer and its field name as a string are necessary so that reflection can be used to read the struct tag on the field to get the module namespace and inline modul

(structPointer any, fieldName string)

Source from the content-addressed store, hash-verified

186// successfully, this method clears the json.RawMessage(s) in the field since
187// the raw JSON is no longer needed, and this allows the GC to free up memory.
188func (ctx Context) LoadModule(structPointer any, fieldName string) (any, error) {
189 val := reflect.ValueOf(structPointer).Elem().FieldByName(fieldName)
190 typ := val.Type()
191
192 field, ok := reflect.TypeOf(structPointer).Elem().FieldByName(fieldName)
193 if !ok {
194 panic(fmt.Sprintf("field %s does not exist in %#v", fieldName, structPointer))
195 }
196
197 opts, err := ParseStructTag(field.Tag.Get("caddy"))
198 if err != nil {
199 panic(fmt.Sprintf("malformed tag on field %s: %v", fieldName, err))
200 }
201
202 moduleNamespace, ok := opts["namespace"]
203 if !ok {
204 panic(fmt.Sprintf("missing 'namespace' key in struct tag on field %s", fieldName))
205 }
206 inlineModuleKey := opts["inline_key"]
207
208 var result any
209
210 switch val.Kind() {
211 case reflect.Slice:
212 if isJSONRawMessage(typ) {
213 // val is `json.RawMessage` ([]uint8 under the hood)
214
215 if inlineModuleKey == "" {
216 panic("unable to determine module name without inline_key when type is not a ModuleMap")
217 }
218 val, err := ctx.loadModuleInline(inlineModuleKey, moduleNamespace, val.Interface().(json.RawMessage))
219 if err != nil {
220 return nil, err
221 }
222 result = val
223 } else if isJSONRawMessage(typ.Elem()) {
224 // val is `[]json.RawMessage`
225
226 if inlineModuleKey == "" {
227 panic("unable to determine module name without inline_key because type is not a ModuleMap")
228 }
229 var all []any
230 for i := 0; i < val.Len(); i++ {
231 val, err := ctx.loadModuleInline(inlineModuleKey, moduleNamespace, val.Index(i).Interface().(json.RawMessage))
232 if err != nil {
233 return nil, fmt.Errorf("position %d: %v", i, err)
234 }
235 all = append(all, val)
236 }
237 result = all
238 } else if typ.Elem().Kind() == reflect.Slice && isJSONRawMessage(typ.Elem().Elem()) {
239 // val is `[][]json.RawMessage`
240
241 if inlineModuleKey == "" {
242 panic("unable to determine module name without inline_key because type is not a ModuleMap")
243 }
244 var all [][]any
245 for i := 0; i < val.Len(); i++ {

Callers 15

cmdImportStorageFunction · 0.95
cmdExportStorageFunction · 0.95
provisionCommonMethod · 0.80
manageIdentityFunction · 0.80
provisionContextFunction · 0.80
finishSettingUpFunction · 0.80
ProvisionMethod · 0.80
ProvisionMethod · 0.80
ProvisionMethod · 0.80

Calls 9

loadModuleInlineMethod · 0.95
ParseStructTagFunction · 0.85
isJSONRawMessageFunction · 0.85
isModuleMapTypeFunction · 0.85
GetMethod · 0.65
TypeMethod · 0.45
LenMethod · 0.45
SetMethod · 0.45

Tested by 3