@@ -20,6 +20,12 @@ public final class BuiltinRegistry {
2020
2121 private final Map <String , BuiltinFunction > builtins = new HashMap <>();
2222
23+ /** Require the input to be a JqArray, throwing a descriptive error if not. */
24+ private static JqArray requireArray (JqValue input , String operation ) {
25+ if (input instanceof JqArray arr ) return arr ;
26+ throw new JqException (operation + " requires array input" );
27+ }
28+
2329 public BuiltinRegistry () {
2430 registerDefaults ();
2531 }
@@ -177,7 +183,7 @@ private void registerDefaults() {
177183
178184 // Collection builtins
179185 register ("map" , 1 , (input , args , env , eval , out ) -> {
180- if (!( input instanceof JqArray arr )) throw new JqException ( "map requires array input " );
186+ JqArray arr = requireArray ( input , "map" );
181187 var results = new ArrayList <JqValue >();
182188 for (JqValue elem : arr .arrayValue ()) {
183189 eval .eval (args .getFirst (), elem , env , results ::add );
@@ -215,7 +221,7 @@ private void registerDefaults() {
215221 });
216222
217223 register ("add" , 0 , (input , args , env , eval , out ) -> {
218- if (!( input instanceof JqArray arr )) throw new JqException ( "add requires array input " );
224+ JqArray arr = requireArray ( input , "add" );
219225 if (arr .arrayValue ().isEmpty ()) {
220226 out .accept (JqNull .NULL );
221227 return ;
@@ -247,12 +253,12 @@ private void registerDefaults() {
247253 });
248254
249255 register ("any" , 0 , (input , args , env , eval , out ) -> {
250- if (!( input instanceof JqArray arr )) throw new JqException ( "any requires array input " );
256+ JqArray arr = requireArray ( input , "any" );
251257 out .accept (JqBoolean .of (arr .arrayValue ().stream ().anyMatch (JqValue ::isTruthy )));
252258 });
253259
254260 register ("any" , 1 , (input , args , env , eval , out ) -> {
255- if (!( input instanceof JqArray arr )) throw new JqException ( "any requires array input " );
261+ JqArray arr = requireArray ( input , "any" );
256262 for (JqValue elem : arr .arrayValue ()) {
257263 var results = eval .eval (args .getFirst (), elem , env );
258264 if (results .stream ().anyMatch (JqValue ::isTruthy )) {
@@ -264,12 +270,12 @@ private void registerDefaults() {
264270 });
265271
266272 register ("all" , 0 , (input , args , env , eval , out ) -> {
267- if (!( input instanceof JqArray arr )) throw new JqException ( "all requires array input " );
273+ JqArray arr = requireArray ( input , "all" );
268274 out .accept (JqBoolean .of (arr .arrayValue ().stream ().allMatch (JqValue ::isTruthy )));
269275 });
270276
271277 register ("all" , 1 , (input , args , env , eval , out ) -> {
272- if (!( input instanceof JqArray arr )) throw new JqException ( "all requires array input " );
278+ JqArray arr = requireArray ( input , "all" );
273279 for (JqValue elem : arr .arrayValue ()) {
274280 var results = eval .eval (args .getFirst (), elem , env );
275281 if (results .stream ().noneMatch (JqValue ::isTruthy )) {
@@ -281,14 +287,14 @@ private void registerDefaults() {
281287 });
282288
283289 register ("flatten" , 0 , (input , args , env , eval , out ) -> {
284- if (!( input instanceof JqArray arr )) throw new JqException ( "flatten requires array input " );
290+ JqArray arr = requireArray ( input , "flatten" );
285291 var result = new ArrayList <JqValue >();
286292 flattenArray (arr , result , Integer .MAX_VALUE );
287293 out .accept (JqArray .of (result ));
288294 });
289295
290296 register ("flatten" , 1 , (input , args , env , eval , out ) -> {
291- if (!( input instanceof JqArray arr )) throw new JqException ( "flatten requires array input " );
297+ JqArray arr = requireArray ( input , "flatten" );
292298 eval .eval (args .getFirst (), input , env , depthVal -> {
293299 int depth = (int ) depthVal .longValue ();
294300 if (depth < 0 ) throw new JqException ("flatten depth must not be negative" );
@@ -299,14 +305,14 @@ private void registerDefaults() {
299305 });
300306
301307 register ("sort" , 0 , (input , args , env , eval , out ) -> {
302- if (!( input instanceof JqArray arr )) throw new JqException ( "sort requires array input " );
308+ JqArray arr = requireArray ( input , "sort" );
303309 var list = new ArrayList <>(arr .arrayValue ());
304310 list .sort (JqValue ::compareTo );
305311 out .accept (JqArray .of (list ));
306312 });
307313
308314 register ("sort_by" , 1 , (input , args , env , eval , out ) -> {
309- if (!( input instanceof JqArray arr )) throw new JqException ( "sort_by requires array input " );
315+ JqArray arr = requireArray ( input , "sort_by" );
310316 var list = new ArrayList <>(arr .arrayValue ());
311317 list .sort ((a , b ) -> {
312318 var keysA = eval .eval (args .getFirst (), a , env );
@@ -321,7 +327,7 @@ private void registerDefaults() {
321327 });
322328
323329 register ("group_by" , 1 , (input , args , env , eval , out ) -> {
324- if (!( input instanceof JqArray arr )) throw new JqException ( "group_by requires array input " );
330+ JqArray arr = requireArray ( input , "group_by" );
325331 var groups = new LinkedHashMap <String , List <JqValue >>();
326332 var sortedList = new ArrayList <>(arr .arrayValue ());
327333 sortedList .sort ((a , b ) -> {
@@ -340,7 +346,7 @@ private void registerDefaults() {
340346 });
341347
342348 register ("unique" , 0 , (input , args , env , eval , out ) -> {
343- if (!( input instanceof JqArray arr )) throw new JqException ( "unique requires array input " );
349+ JqArray arr = requireArray ( input , "unique" );
344350 var seen = new LinkedHashSet <String >();
345351 var result = new ArrayList <JqValue >();
346352 var sorted = new ArrayList <>(arr .arrayValue ());
@@ -354,7 +360,7 @@ private void registerDefaults() {
354360 });
355361
356362 register ("unique_by" , 1 , (input , args , env , eval , out ) -> {
357- if (!( input instanceof JqArray arr )) throw new JqException ( "unique_by requires array input " );
363+ JqArray arr = requireArray ( input , "unique_by" );
358364 var seen = new LinkedHashSet <String >();
359365 var result = new ArrayList <JqValue >();
360366 for (JqValue elem : arr .arrayValue ()) {
@@ -425,7 +431,7 @@ private void registerDefaults() {
425431 });
426432
427433 register ("transpose" , 0 , (input , args , env , eval , out ) -> {
428- if (!( input instanceof JqArray arr )) throw new JqException ( "transpose requires array input " );
434+ JqArray arr = requireArray ( input , "transpose" );
429435 int maxLen = 0 ;
430436 for (JqValue v : arr .arrayValue ()) {
431437 if (v instanceof JqArray a ) maxLen = Math .max (maxLen , a .arrayValue ().size ());
@@ -653,7 +659,7 @@ private void registerDefaults() {
653659 });
654660
655661 register ("join" , 1 , (input , args , env , eval , out ) -> {
656- if (!( input instanceof JqArray arr )) throw new JqException ( "join requires array input " );
662+ JqArray arr = requireArray ( input , "join" );
657663 eval .eval (args .getFirst (), input , env , sep -> {
658664 String sepStr = sep instanceof JqString s ? s .stringValue () : sep .toJsonString ();
659665 var sb = new StringBuilder ();
@@ -808,7 +814,7 @@ private void registerDefaults() {
808814 });
809815
810816 register ("implode" , 0 , (input , args , env , eval , out ) -> {
811- if (!( input instanceof JqArray arr )) throw new JqException ( "implode input must be an array " );
817+ JqArray arr = requireArray ( input , "implode " );
812818 var sb = new StringBuilder ();
813819 for (JqValue v : arr .arrayValue ()) {
814820 if (!(v instanceof JqNumber n )) {
@@ -1119,7 +1125,7 @@ private void registerDefaults() {
11191125 });
11201126
11211127 register ("from_entries" , 0 , (input , args , env , eval , out ) -> {
1122- if (!( input instanceof JqArray arr )) throw new JqException ( "from_entries requires array " );
1128+ JqArray arr = requireArray ( input , "from_entries" );
11231129 var map = new LinkedHashMap <String , JqValue >();
11241130 for (JqValue v : arr .arrayValue ()) {
11251131 if (v instanceof JqObject obj ) {
@@ -1694,7 +1700,7 @@ private void registerDefaults() {
16941700
16951701 // combinations
16961702 register ("combinations" , 0 , (input , args , env , eval , out ) -> {
1697- if (!( input instanceof JqArray arr )) throw new JqException ( "combinations requires array of arrays " );
1703+ JqArray arr = requireArray ( input , "combinations" );
16981704 var arrays = new ArrayList <List <JqValue >>();
16991705 for (JqValue v : arr .arrayValue ()) {
17001706 if (v instanceof JqArray a ) {
@@ -1708,7 +1714,7 @@ private void registerDefaults() {
17081714
17091715 register ("combinations" , 1 , (input , args , env , eval , out ) -> {
17101716 int n = (int ) eval .eval (args .getFirst (), input , env ).getFirst ().longValue ();
1711- if (!( input instanceof JqArray arr )) throw new JqException ( "combinations requires array " );
1717+ JqArray arr = requireArray ( input , "combinations" );
17121718 var arrays = new ArrayList <List <JqValue >>();
17131719 for (int i = 0 ; i < n ; i ++) {
17141720 arrays .add (arr .arrayValue ());
@@ -1730,9 +1736,7 @@ private void registerDefaults() {
17301736
17311737 // bsearch(x) - binary search in sorted array
17321738 register ("bsearch" , 1 , (input , args , env , eval , out ) -> {
1733- if (!(input instanceof JqArray arr )) {
1734- throw new JqException (input .type ().jqName () + " (" + input .toJsonString () + ") cannot be searched from" );
1735- }
1739+ JqArray arr = requireArray (input , "bsearch" );
17361740 eval .eval (args .getFirst (), input , env , target -> {
17371741 List <JqValue > list = arr .arrayValue ();
17381742 int lo = 0 , hi = list .size () - 1 ;
@@ -1983,9 +1987,7 @@ private void registerDefaults() {
19831987 // JOIN(idx; idx_expr) — for each element $x in input array, output [$x, idx[$x | idx_expr]]
19841988 register ("JOIN" , 2 , (input , args , env , eval , out ) -> {
19851989 JqValue idx = eval .eval (args .get (0 ), input , env ).getFirst ();
1986- if (!(input instanceof JqArray arr )) {
1987- throw new JqTypeError ("Cannot iterate over " + input .type ().jqName ());
1988- }
1990+ JqArray arr = requireArray (input , "JOIN" );
19891991 var results = new java .util .ArrayList <JqValue >();
19901992 for (JqValue elem : arr .arrayValue ()) {
19911993 JqValue key = eval .eval (args .get (1 ), elem , env ).getFirst ();
0 commit comments