MCPcopy Index your code
hub / github.com/foxcpp/maddy / ModuleFromNode

Function ModuleFromNode

framework/config/module/modconfig.go:102–148  ·  view source on GitHub ↗

ModuleFromNode does all work to create or get existing module object with a certain type. It is not used by top-level module definitions, only for references from other modules configuration blocks. inlineCfg should contain configuration directives for inline declarations. args should contain value

(preferredNamespace string, args []string, inlineCfg config.Node, globals map[string]interface{}, moduleIface interface{})

Source from the content-addressed store, hash-verified

100// Module with name preferredNamespace + "." + args[0] will be preferred over just args[0].
101// It can be omitted.
102func ModuleFromNode(preferredNamespace string, args []string, inlineCfg config.Node, globals map[string]interface{}, moduleIface interface{}) error {
103 if len(args) == 0 {
104 return parser.NodeErr(inlineCfg, "at least one argument is required")
105 }
106
107 referenceExisting := strings.HasPrefix(args[0], "&")
108
109 var modObj module.Module
110 var err error
111 if referenceExisting {
112 if len(args) != 1 || inlineCfg.Children != nil {
113 return parser.NodeErr(inlineCfg, "exactly one argument is required to use existing config block")
114 }
115 modObj, err = container.Global.Modules.Get(args[0][1:])
116 log.Debugf("%s:%d: reference %s", inlineCfg.File, inlineCfg.Line, args[0])
117 } else {
118 log.Debugf("%s:%d: new module %s %v", inlineCfg.File, inlineCfg.Line, args[0], args[1:])
119 modObj, err = createInlineModule(container.Global, preferredNamespace, args[0])
120 }
121 if err != nil {
122 return err
123 }
124
125 // NOTE: This will panic if moduleIface is not a pointer.
126 modIfaceType := reflect.TypeOf(moduleIface).Elem()
127 modObjType := reflect.TypeOf(modObj)
128
129 if modIfaceType.Kind() == reflect.Interface {
130 // Case for assignment to module interface type.
131 if !modObjType.Implements(modIfaceType) && !modObjType.AssignableTo(modIfaceType) {
132 return parser.NodeErr(inlineCfg, "module %s (%s) doesn't implement %v interface", modObj.Name(), modObj.InstanceName(), modIfaceType)
133 }
134 } else if !modObjType.AssignableTo(modIfaceType) {
135 // Case for assignment to concrete module type. Used in "module groups".
136 return parser.NodeErr(inlineCfg, "module %s (%s) is not %v", modObj.Name(), modObj.InstanceName(), modIfaceType)
137 }
138
139 reflect.ValueOf(moduleIface).Elem().Set(reflect.ValueOf(modObj))
140
141 if !referenceExisting {
142 if err := configureInlineModule(modObj, args[1:], globals, inlineCfg); err != nil {
143 return err
144 }
145 }
146
147 return nil
148}
149
150// GroupFromNode provides a special kind of ModuleFromNode syntax that allows
151// to omit the module name when defining inine configuration. If it is not

Callers 7

GroupFromNodeFunction · 0.85
MessageCheckFunction · 0.85
DeliveryTargetFunction · 0.85
MsgModifierFunction · 0.85
IMAPFilterFunction · 0.85
StorageDirectiveFunction · 0.85
TableDirectiveFunction · 0.85

Calls 7

NameMethod · 0.95
InstanceNameMethod · 0.95
DebugfFunction · 0.92
createInlineModuleFunction · 0.85
configureInlineModuleFunction · 0.85
GetMethod · 0.45
SetMethod · 0.45

Tested by

no test coverage detected