1// Copyright 2018 The OPA Authors. All rights reserved. 2// Use of this source code is governed by an Apache2 3// license that can be found in the LICENSE file. 4 5package topdown 6 7import ( 8 "github.com/open-policy-agent/opa/ast" 9 "github.com/open-policy-agent/opa/topdown/builtins" 10) 11 12func builtinArrayConcat(a, b ast.Value) (ast.Value, error) { 13 arrA, err := builtins.ArrayOperand(a, 1) 14 if err != nil { 15 return nil, err 16 } 17 18 arrB, err := builtins.ArrayOperand(b, 2) 19 if err != nil { 20 return nil, err 21 } 22 23 arrC := make(ast.Array, 0, len(arrA)+len(arrB)) 24 25 for _, elemA := range arrA { 26 arrC = append(arrC, elemA) 27 } 28 29 for _, elemB := range arrB { 30 arrC = append(arrC, elemB) 31 } 32 33 return arrC, nil 34} 35 36func builtinArraySlice(a, i, j ast.Value) (ast.Value, error) { 37 arr, err := builtins.ArrayOperand(a, 1) 38 if err != nil { 39 return nil, err 40 } 41 42 startIndex, err := builtins.IntOperand(i, 2) 43 if err != nil { 44 return nil, err 45 } 46 47 stopIndex, err := builtins.IntOperand(j, 3) 48 if err != nil { 49 return nil, err 50 } 51 52 // Return empty array if bounds cannot be clamped sensibly. 53 if (startIndex >= stopIndex) || (startIndex <= 0 && stopIndex <= 0) { 54 return arr[0:0], nil 55 } 56 57 // Clamp bounds to avoid out-of-range errors. 58 if startIndex < 0 { 59 startIndex = 0 60 } 61 62 if stopIndex > len(arr) { 63 stopIndex = len(arr) 64 } 65 66 arrb := arr[startIndex:stopIndex] 67 68 return arrb, nil 69 70} 71 72func init() { 73 RegisterFunctionalBuiltin2(ast.ArrayConcat.Name, builtinArrayConcat) 74 RegisterFunctionalBuiltin3(ast.ArraySlice.Name, builtinArraySlice) 75} 76