Skip to content

Commit 82bb7df

Browse files
committed
Add take()
1 parent 418fed5 commit 82bb7df

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

builtin/builtin.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,42 @@ var Builtins = []*ast.Function{
524524
return runtime.Fetch(args[0], args[1]), nil
525525
},
526526
},
527+
{
528+
Name: "take",
529+
Func: func(args ...any) (any, error) {
530+
if len(args) != 2 {
531+
return nil, fmt.Errorf("invalid number of arguments (expected 2, got %d)", len(args))
532+
}
533+
v := reflect.ValueOf(args[0])
534+
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
535+
return nil, fmt.Errorf("cannot take from %s", v.Kind())
536+
}
537+
n := reflect.ValueOf(args[1])
538+
if !n.CanInt() {
539+
return nil, fmt.Errorf("cannot take %s elements", n.Kind())
540+
}
541+
if n.Int() > int64(v.Len()) {
542+
return args[0], nil
543+
}
544+
return v.Slice(0, int(n.Int())).Interface(), nil
545+
},
546+
Validate: func(args []reflect.Type) (reflect.Type, error) {
547+
if len(args) != 2 {
548+
return anyType, fmt.Errorf("invalid number of arguments (expected 2, got %d)", len(args))
549+
}
550+
switch kind(args[0]) {
551+
case reflect.Interface, reflect.Slice, reflect.Array:
552+
default:
553+
return anyType, fmt.Errorf("cannot take from %s", args[0])
554+
}
555+
switch kind(args[1]) {
556+
case reflect.Interface, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
557+
default:
558+
return anyType, fmt.Errorf("cannot take %s elements", args[1])
559+
}
560+
return args[0], nil
561+
},
562+
},
527563
{
528564
Name: "keys",
529565
Func: func(args ...any) (any, error) {

builtin/builtin_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ func TestBuiltin(t *testing.T) {
9292
{`get(ArrayOfAny, 1)`, "2"},
9393
{`get({foo: 1, bar: 2}, "foo")`, 1},
9494
{`get({foo: 1, bar: 2}, "unknown")`, nil},
95+
{`take(ArrayOfString, 2)`, []string{"foo", "bar"}},
96+
{`take(ArrayOfString, 99)`, []string{"foo", "bar", "baz"}},
9597
{`"foo" in keys({foo: 1, bar: 2})`, true},
9698
{`1 in values({foo: 1, bar: 2})`, true},
9799
{`len(toPairs({foo: 1, bar: 2}))`, 2},
@@ -123,6 +125,7 @@ func TestBuiltin_works_with_any(t *testing.T) {
123125
arity int
124126
}{
125127
"get": {2},
128+
"take": {2},
126129
"sortBy": {2},
127130
}
128131

0 commit comments

Comments
 (0)