...
1 package exec
2
3 import (
4 "strings"
5
6 "github.com/noirbizarre/gonja/nodes"
7 "github.com/pkg/errors"
8
9 )
10
11
12 type Macro func(params *VarArgs) *Value
13
14 type MacroSet map[string]Macro
15
16
17 func (ms MacroSet) Exists(name string) bool {
18 _, existing := ms[name]
19 return existing
20 }
21
22
23
24
25
26
27
28
29 func (ms *MacroSet) Register(name string, fn Macro) error {
30 if ms.Exists(name) {
31 return errors.Errorf("filter with name '%s' is already registered", name)
32 }
33 (*ms)[name] = fn
34 return nil
35 }
36
37
38
39 func (ms *MacroSet) Replace(name string, fn Macro) error {
40 if !ms.Exists(name) {
41 return errors.Errorf("filter with name '%s' does not exist (therefore cannot be overridden)", name)
42 }
43 (*ms)[name] = fn
44 return nil
45 }
46
47 func MacroNodeToFunc(node *nodes.Macro, r *Renderer) (Macro, error) {
48
49 defaultKwargs := []*KwArg{}
50 var err error
51 for _, pair := range node.Kwargs {
52 key := r.Eval(pair.Key).String()
53 value := r.Eval(pair.Value)
54 if value.IsError() {
55 return nil, errors.Wrapf(value, `Unable to evaluate parameter %s=%s`, key, pair.Value)
56 }
57 defaultKwargs = append(defaultKwargs, &KwArg{key, value.Interface()})
58 }
59
60 return func(params *VarArgs) *Value {
61 var out strings.Builder
62 sub := r.Inherit()
63 sub.Out = &out
64
65 if err != nil {
66 return AsValue(err)
67 }
68 p := params.Expect(len(node.Args), defaultKwargs)
69 if p.IsError() {
70 return AsValue(errors.Wrapf(p, `Wrong '%s' macro signature`, node.Name))
71 }
72 for idx, arg := range p.Args {
73 sub.Ctx.Set(node.Args[idx], arg)
74 }
75 for key, value := range p.KwArgs {
76 sub.Ctx.Set(key, value)
77 }
78 err := sub.ExecuteWrapper(node.Wrapper)
79 if err != nil {
80 return AsValue(errors.Wrapf(err, `Unable to execute macro '%s`, node.Name))
81 }
82 return AsSafeValue(out.String())
83 }, err
84 }
85
View as plain text