aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go88
1 files changed, 88 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go
index e2c77c5..d3cc341 100644
--- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go
@@ -119,6 +119,75 @@ var ConcatFunc = function.New(&function.Spec{
119 }, 119 },
120}) 120})
121 121
122var RangeFunc = function.New(&function.Spec{
123 VarParam: &function.Parameter{
124 Name: "params",
125 Type: cty.Number,
126 },
127 Type: function.StaticReturnType(cty.List(cty.Number)),
128 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
129 var start, end, step cty.Value
130 switch len(args) {
131 case 1:
132 if args[0].LessThan(cty.Zero).True() {
133 start, end, step = cty.Zero, args[0], cty.NumberIntVal(-1)
134 } else {
135 start, end, step = cty.Zero, args[0], cty.NumberIntVal(1)
136 }
137 case 2:
138 if args[1].LessThan(args[0]).True() {
139 start, end, step = args[0], args[1], cty.NumberIntVal(-1)
140 } else {
141 start, end, step = args[0], args[1], cty.NumberIntVal(1)
142 }
143 case 3:
144 start, end, step = args[0], args[1], args[2]
145 default:
146 return cty.NilVal, fmt.Errorf("must have one, two, or three arguments")
147 }
148
149 var vals []cty.Value
150
151 if step == cty.Zero {
152 return cty.NilVal, function.NewArgErrorf(2, "step must not be zero")
153 }
154 down := step.LessThan(cty.Zero).True()
155
156 if down {
157 if end.GreaterThan(start).True() {
158 return cty.NilVal, function.NewArgErrorf(1, "end must be less than start when step is negative")
159 }
160 } else {
161 if end.LessThan(start).True() {
162 return cty.NilVal, function.NewArgErrorf(1, "end must be greater than start when step is positive")
163 }
164 }
165
166 num := start
167 for {
168 if down {
169 if num.LessThanOrEqualTo(end).True() {
170 break
171 }
172 } else {
173 if num.GreaterThanOrEqualTo(end).True() {
174 break
175 }
176 }
177 if len(vals) >= 1024 {
178 // Artificial limit to prevent bad arguments from consuming huge amounts of memory
179 return cty.NilVal, fmt.Errorf("more than 1024 values were generated; either decrease the difference between start and end or use a smaller step")
180 }
181 vals = append(vals, num)
182 num = num.Add(step)
183 }
184 if len(vals) == 0 {
185 return cty.ListValEmpty(cty.Number), nil
186 }
187 return cty.ListVal(vals), nil
188 },
189})
190
122// Concat takes one or more sequences (lists or tuples) and returns the single 191// Concat takes one or more sequences (lists or tuples) and returns the single
123// sequence that results from concatenating them together in order. 192// sequence that results from concatenating them together in order.
124// 193//
@@ -128,3 +197,22 @@ var ConcatFunc = function.New(&function.Spec{
128func Concat(seqs ...cty.Value) (cty.Value, error) { 197func Concat(seqs ...cty.Value) (cty.Value, error) {
129 return ConcatFunc.Call(seqs) 198 return ConcatFunc.Call(seqs)
130} 199}
200
201// Range creates a list of numbers by starting from the given starting value,
202// then adding the given step value until the result is greater than or
203// equal to the given stopping value. Each intermediate result becomes an
204// element in the resulting list.
205//
206// When all three parameters are set, the order is (start, end, step). If
207// only two parameters are set, they are the start and end respectively and
208// step defaults to 1. If only one argument is set, it gives the end value
209// with start defaulting to 0 and step defaulting to 1.
210//
211// Because the resulting list must be fully buffered in memory, there is an
212// artificial cap of 1024 elements, after which this function will return
213// an error to avoid consuming unbounded amounts of memory. The Range function
214// is primarily intended for creating small lists of indices to iterate over,
215// so there should be no reason to generate huge lists with it.
216func Range(params ...cty.Value) (cty.Value, error) {
217 return RangeFunc.Call(params)
218}