1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package list
17
18 import (
19 "fmt"
20 "sort"
21
22 "cuelang.org/go/cue"
23 "cuelang.org/go/cue/errors"
24 "cuelang.org/go/cue/token"
25 "cuelang.org/go/internal/core/adt"
26 "cuelang.org/go/internal/pkg"
27 )
28
29
30
31
32
33
34
35
36
37
38
39 func Drop(x []cue.Value, n int) ([]cue.Value, error) {
40 if n < 0 {
41 return nil, fmt.Errorf("negative index")
42 }
43
44 if n > len(x) {
45 return []cue.Value{}, nil
46 }
47
48 return x[n:], nil
49 }
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 func FlattenN(xs cue.Value, depth int) ([]cue.Value, error) {
103 var flattenN func(cue.Value, int) ([]cue.Value, error)
104 flattenN = func(xs cue.Value, depth int) ([]cue.Value, error) {
105 var res []cue.Value
106 iter, err := xs.List()
107 if err != nil {
108 return nil, err
109 }
110 for iter.Next() {
111 val, _ := iter.Value().Default()
112 if val.Kind() == cue.ListKind && depth != 0 {
113 d := depth - 1
114 values, err := flattenN(val, d)
115 if err != nil {
116 return nil, err
117 }
118 res = append(res, values...)
119 } else {
120 res = append(res, val)
121 }
122 }
123 return res, nil
124 }
125 return flattenN(xs, depth)
126 }
127
128
129
130
131
132
133
134
135
136
137 func Repeat(x []cue.Value, count int) ([]cue.Value, error) {
138 if count < 0 {
139 return nil, fmt.Errorf("negative count")
140 }
141 var a []cue.Value
142 for i := 0; i < count; i++ {
143 a = append(a, x...)
144 }
145 return a, nil
146 }
147
148
149
150
151
152
153 func Concat(a []cue.Value) ([]cue.Value, error) {
154 var res []cue.Value
155 for _, e := range a {
156 iter, err := e.List()
157 if err != nil {
158 return nil, err
159 }
160 for iter.Next() {
161 res = append(res, iter.Value())
162 }
163 }
164 return res, nil
165 }
166
167
168
169
170
171
172
173
174
175
176 func Take(x []cue.Value, n int) ([]cue.Value, error) {
177 if n < 0 {
178 return nil, fmt.Errorf("negative index")
179 }
180
181 if n > len(x) {
182 return x, nil
183 }
184
185 return x[:n], nil
186 }
187
188
189
190
191
192
193
194
195
196
197
198 func Slice(x []cue.Value, i, j int) ([]cue.Value, error) {
199 if i < 0 {
200 return nil, fmt.Errorf("negative index")
201 }
202
203 if i > j {
204 return nil, fmt.Errorf("invalid index: %v > %v", i, j)
205 }
206
207 if i > len(x) {
208 return nil, fmt.Errorf("slice bounds out of range")
209 }
210
211 if j > len(x) {
212 return nil, fmt.Errorf("slice bounds out of range")
213 }
214
215 return x[i:j], nil
216 }
217
218
219 func MinItems(list pkg.List, n int) (bool, error) {
220 count := len(list.Elems())
221 if count >= n {
222 return true, nil
223 }
224 code := adt.EvalError
225 if list.IsOpen() {
226 code = adt.IncompleteError
227 }
228 return false, pkg.ValidationError{B: &adt.Bottom{
229 Code: code,
230 Err: errors.Newf(token.NoPos, "len(list) < MinItems(%[2]d) (%[1]d < %[2]d)", count, n),
231 }}
232 }
233
234
235 func MaxItems(list pkg.List, n int) (bool, error) {
236 count := len(list.Elems())
237 if count > n {
238 return false, pkg.ValidationError{B: &adt.Bottom{
239 Code: adt.EvalError,
240 Err: errors.Newf(token.NoPos, "len(list) > MaxItems(%[2]d) (%[1]d > %[2]d)", count, n),
241 }}
242 }
243
244 return true, nil
245 }
246
247
248 func UniqueItems(a []cue.Value) bool {
249 b := []string{}
250 for _, v := range a {
251 b = append(b, fmt.Sprintf("%+v", v))
252 }
253 sort.Strings(b)
254 for i := 1; i < len(b); i++ {
255 if b[i-1] == b[i] {
256 return false
257 }
258 }
259 return true
260 }
261
262
263
264 func Contains(a []cue.Value, v cue.Value) bool {
265 for _, w := range a {
266 if v.Equals(w) {
267 return true
268 }
269 }
270 return false
271 }
272
View as plain text