...
1 package builtins
2
3 import (
4 "github.com/pkg/errors"
5
6 "github.com/noirbizarre/gonja/exec"
7 "github.com/noirbizarre/gonja/utils"
8 )
9
10 var Globals = exec.NewContext(map[string]interface{}{
11 "cycler": Cycler,
12 "dict": Dict,
13 "joiner": Joiner,
14 "lipsum": Lipsum,
15 "namespace": Namespace,
16 "range": Range,
17 })
18
19 func Range(va *exec.VarArgs) <-chan int {
20 var (
21 start = 0
22 stop = -1
23 step = 1
24 )
25 switch len(va.Args) {
26 case 1:
27 stop = va.Args[0].Integer()
28 case 2:
29 start = va.Args[0].Integer()
30 stop = va.Args[1].Integer()
31 case 3:
32 start = va.Args[0].Integer()
33 stop = va.Args[1].Integer()
34 step = va.Args[2].Integer()
35
36
37 }
38 chnl := make(chan int)
39 go func() {
40 for i := start; i < stop; i += step {
41 chnl <- i
42 }
43
44
45 close(chnl)
46 }()
47 return chnl
48 }
49
50 func Dict(va *exec.VarArgs) *exec.Value {
51 dict := exec.NewDict()
52 for key, value := range va.KwArgs {
53 dict.Pairs = append(dict.Pairs, &exec.Pair{
54 Key: exec.AsValue(key),
55 Value: value,
56 })
57 }
58 return exec.AsValue(dict)
59 }
60
61 type cycler struct {
62 values []string
63 idx int
64 getters map[string]interface{}
65 }
66
67 func (c *cycler) Reset() {
68 c.idx = 0
69 c.getters["current"] = c.values[c.idx]
70 }
71
72 func (c *cycler) Next() string {
73 c.idx++
74 value := c.getters["current"].(string)
75 if c.idx >= len(c.values) {
76 c.idx = 0
77 }
78 c.getters["current"] = c.values[c.idx]
79 return value
80 }
81
82 func Cycler(va *exec.VarArgs) *exec.Value {
83 c := &cycler{}
84 for _, arg := range va.Args {
85 c.values = append(c.values, arg.String())
86 }
87 c.getters = map[string]interface{}{
88 "next": c.Next,
89 "reset": c.Reset,
90 }
91 c.Reset()
92 return exec.AsValue(c.getters)
93 }
94
95 type joiner struct {
96 sep string
97 first bool
98 }
99
100 func (j *joiner) String() string {
101 if !j.first {
102 j.first = true
103 return ""
104 }
105 return j.sep
106 }
107
108 func Joiner(va *exec.VarArgs) *exec.Value {
109 p := va.ExpectKwArgs([]*exec.KwArg{{"sep", ","}})
110 if p.IsError() {
111 return exec.AsValue(errors.Wrapf(p, `wrong signature for 'joiner'`))
112 }
113 sep := p.KwArgs["sep"].String()
114 j := &joiner{sep: sep}
115 return exec.AsValue(j.String)
116 }
117
118
119
120 func Namespace(va *exec.VarArgs) map[string]interface{} {
121 ns := map[string]interface{}{}
122 for key, value := range va.KwArgs {
123 ns[key] = value
124 }
125 return ns
126 }
127
128 func Lipsum(va *exec.VarArgs) *exec.Value {
129 p := va.ExpectKwArgs([]*exec.KwArg{
130 {"n", 5},
131 {"html", true},
132 {"min", 20},
133 {"max", 100},
134 })
135 if p.IsError() {
136 return exec.AsValue(errors.Wrapf(p, `wrong signature for 'lipsum'`))
137 }
138 n := p.KwArgs["n"].Integer()
139 html := p.KwArgs["html"].Bool()
140 min := p.KwArgs["min"].Integer()
141 max := p.KwArgs["max"].Integer()
142 return exec.AsSafeValue(utils.Lipsum(n, html, min, max))
143 }
144
View as plain text