@rimbu/deep 0.12.1 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main/match.js +109 -34
- package/dist/main/match.js.map +1 -1
- package/dist/module/match.js +108 -33
- package/dist/module/match.js.map +1 -1
- package/dist/types/match.d.ts +37 -15
- package/package.json +4 -4
- package/src/match.ts +240 -44
package/src/match.ts
CHANGED
|
@@ -25,7 +25,7 @@ export namespace Match {
|
|
|
25
25
|
* Determines the various allowed match types for given type `T`.
|
|
26
26
|
* @typeparam T - the input value type
|
|
27
27
|
* @typeparam C - utility type
|
|
28
|
-
* @typeparam P - the
|
|
28
|
+
* @typeparam P - the parent type
|
|
29
29
|
* @typeparam R - the root object type
|
|
30
30
|
*/
|
|
31
31
|
export type Entry<T, C, P, R> = IsAnyFunc<T> extends true
|
|
@@ -36,7 +36,15 @@ export namespace Match {
|
|
|
36
36
|
Match.WithResult<T, P, R, Match.Obj<T, C, P, R>>
|
|
37
37
|
: IsArray<T> extends true
|
|
38
38
|
? // determine allowed match values for array or tuple
|
|
39
|
-
|
|
39
|
+
| Match.Arr<T, C, P, R>
|
|
40
|
+
| Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[]
|
|
41
|
+
| Match.Func<
|
|
42
|
+
T,
|
|
43
|
+
P,
|
|
44
|
+
R,
|
|
45
|
+
| Match.Arr<T, C, P, R>
|
|
46
|
+
| Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[]
|
|
47
|
+
>
|
|
40
48
|
: // only accept values with same interface
|
|
41
49
|
Match.WithResult<T, P, R, { [K in keyof C]: C[K & keyof T] }>;
|
|
42
50
|
|
|
@@ -44,7 +52,7 @@ export namespace Match {
|
|
|
44
52
|
* The type that determines allowed matchers for objects.
|
|
45
53
|
* @typeparam T - the input value type
|
|
46
54
|
* @typeparam C - utility type
|
|
47
|
-
* @typeparam P - the
|
|
55
|
+
* @typeparam P - the parent type
|
|
48
56
|
* @typeparam R - the root object type
|
|
49
57
|
*/
|
|
50
58
|
export type Obj<T, C, P, R> =
|
|
@@ -65,20 +73,31 @@ export namespace Match {
|
|
|
65
73
|
* The type that determines allowed matchers for arrays/tuples.
|
|
66
74
|
* @typeparam T - the input value type
|
|
67
75
|
* @typeparam C - utility type
|
|
68
|
-
* @typeparam P - the
|
|
76
|
+
* @typeparam P - the parent type
|
|
69
77
|
* @typeparam R - the root object type
|
|
70
78
|
*/
|
|
71
79
|
export type Arr<T, C, P, R> =
|
|
72
80
|
| C
|
|
73
81
|
| Match.CompoundForArr<T, C, P, R>
|
|
74
|
-
|
|
|
82
|
+
| Match.TraversalForArr<T, C, R>
|
|
83
|
+
| (Match.TupIndices<T, C, R> & {
|
|
84
|
+
[K in Match.CompoundType | Match.ArrayTraversalType]?: never;
|
|
85
|
+
});
|
|
75
86
|
|
|
87
|
+
/**
|
|
88
|
+
* A type that either directly results in result type `S` or is a function taking the value, parent, and root values, and
|
|
89
|
+
* returns a value of type `S`.
|
|
90
|
+
* @typeparam T - the input value type
|
|
91
|
+
* @typeparam P - the parent type
|
|
92
|
+
* @typeparam R - the root object type
|
|
93
|
+
* @typeparam S - the result type
|
|
94
|
+
*/
|
|
76
95
|
export type WithResult<T, P, R, S> = S | Match.Func<T, P, R, S>;
|
|
77
96
|
|
|
78
97
|
/**
|
|
79
98
|
* Type used to determine the allowed function types. Always includes booleans.
|
|
80
99
|
* @typeparam T - the input value type
|
|
81
|
-
* @typeparam P - the
|
|
100
|
+
* @typeparam P - the parent type
|
|
82
101
|
* @typeparam R - the root object type
|
|
83
102
|
* @typeparam S - the allowed return value type
|
|
84
103
|
*/
|
|
@@ -103,6 +122,11 @@ export namespace Match {
|
|
|
103
122
|
*/
|
|
104
123
|
export type CompoundType = 'every' | 'some' | 'none' | 'single';
|
|
105
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Keys used to indicate an array match traversal.
|
|
127
|
+
*/
|
|
128
|
+
export type ArrayTraversalType = `${CompoundType}Item`;
|
|
129
|
+
|
|
106
130
|
/**
|
|
107
131
|
* Compount matcher for objects, can only be an array staring with a compound type keyword.
|
|
108
132
|
* @typeparam T - the input value type
|
|
@@ -123,15 +147,31 @@ export namespace Match {
|
|
|
123
147
|
* @typeparam R - the root object type
|
|
124
148
|
*/
|
|
125
149
|
export type CompoundForArr<T, C, P, R> = {
|
|
126
|
-
[K in CompoundType]: {
|
|
127
|
-
[K2 in CompoundType]?: K2 extends K
|
|
150
|
+
[K in Match.CompoundType]: {
|
|
151
|
+
[K2 in Match.CompoundType]?: K2 extends K
|
|
152
|
+
? Match.Entry<T, C, P, R>[]
|
|
153
|
+
: never;
|
|
154
|
+
};
|
|
155
|
+
}[Match.CompoundType];
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Defines an object containing exactly one `TraversalType` key, having a matcher for the array element type.
|
|
159
|
+
* @typeparam T - the input value type
|
|
160
|
+
* @typeparam C - utility type
|
|
161
|
+
* @typeparam R - the root object type
|
|
162
|
+
*/
|
|
163
|
+
export type TraversalForArr<T, C, R> = {
|
|
164
|
+
[K in Match.ArrayTraversalType]: {
|
|
165
|
+
[K2 in Match.ArrayTraversalType]?: K2 extends K
|
|
166
|
+
? Match.Entry<T[number & keyof T], C[number & keyof C], T, R>
|
|
167
|
+
: never;
|
|
128
168
|
};
|
|
129
|
-
}[
|
|
169
|
+
}[Match.ArrayTraversalType];
|
|
130
170
|
|
|
131
171
|
/**
|
|
132
|
-
* Utility type for collecting
|
|
172
|
+
* Utility type for collecting match failure reasons
|
|
133
173
|
*/
|
|
134
|
-
export type
|
|
174
|
+
export type FailureLog = string[];
|
|
135
175
|
}
|
|
136
176
|
|
|
137
177
|
/**
|
|
@@ -140,7 +180,7 @@ export namespace Match {
|
|
|
140
180
|
* @typeparam C - utility type
|
|
141
181
|
* @param source - the value to match (should be a plain object)
|
|
142
182
|
* @param matcher - a matcher object or a function taking the matcher API and returning a match object
|
|
143
|
-
* @param
|
|
183
|
+
* @param failureLog - (optional) a string array that can be passed to collect reasons why the match failed
|
|
144
184
|
* @example
|
|
145
185
|
* ```ts
|
|
146
186
|
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
@@ -156,9 +196,9 @@ export namespace Match {
|
|
|
156
196
|
export function match<T, C extends Partial<T> = Partial<T>>(
|
|
157
197
|
source: T,
|
|
158
198
|
matcher: Match<T, C>,
|
|
159
|
-
|
|
199
|
+
failureLog?: Match.FailureLog
|
|
160
200
|
): boolean {
|
|
161
|
-
return matchEntry(source, source, source, matcher as any,
|
|
201
|
+
return matchEntry(source, source, source, matcher as any, failureLog);
|
|
162
202
|
}
|
|
163
203
|
|
|
164
204
|
/**
|
|
@@ -169,7 +209,7 @@ function matchEntry<T, C, P, R>(
|
|
|
169
209
|
parent: P,
|
|
170
210
|
root: R,
|
|
171
211
|
matcher: Match.Entry<T, C, P, R>,
|
|
172
|
-
|
|
212
|
+
failureLog?: Match.FailureLog
|
|
173
213
|
): boolean {
|
|
174
214
|
if (Object.is(source, matcher)) {
|
|
175
215
|
// value and target are exactly the same, always will be true
|
|
@@ -179,7 +219,7 @@ function matchEntry<T, C, P, R>(
|
|
|
179
219
|
if (matcher === null || matcher === undefined) {
|
|
180
220
|
// these matchers can only be direct matches, and previously it was determined that
|
|
181
221
|
// they are not equal
|
|
182
|
-
|
|
222
|
+
failureLog?.push(
|
|
183
223
|
`value ${JSON.stringify(source)} did not match matcher ${matcher}`
|
|
184
224
|
);
|
|
185
225
|
|
|
@@ -191,7 +231,7 @@ function matchEntry<T, C, P, R>(
|
|
|
191
231
|
const result = Object.is(source, matcher);
|
|
192
232
|
|
|
193
233
|
if (!result) {
|
|
194
|
-
|
|
234
|
+
failureLog?.push(
|
|
195
235
|
`both value and matcher are functions, but they do not have the same reference`
|
|
196
236
|
);
|
|
197
237
|
}
|
|
@@ -207,7 +247,7 @@ function matchEntry<T, C, P, R>(
|
|
|
207
247
|
// function resulted in a direct match result
|
|
208
248
|
|
|
209
249
|
if (!matcherResult) {
|
|
210
|
-
|
|
250
|
+
failureLog?.push(
|
|
211
251
|
`function matcher returned false for value ${JSON.stringify(source)}`
|
|
212
252
|
);
|
|
213
253
|
}
|
|
@@ -216,22 +256,22 @@ function matchEntry<T, C, P, R>(
|
|
|
216
256
|
}
|
|
217
257
|
|
|
218
258
|
// function resulted in a value that needs to be further matched
|
|
219
|
-
return matchEntry(source, parent, root, matcherResult,
|
|
259
|
+
return matchEntry(source, parent, root, matcherResult, failureLog);
|
|
220
260
|
}
|
|
221
261
|
|
|
222
262
|
if (isPlainObj(source)) {
|
|
223
263
|
// source ia a plain object, can be partially matched
|
|
224
|
-
return matchPlainObj(source, parent, root, matcher as any,
|
|
264
|
+
return matchPlainObj(source, parent, root, matcher as any, failureLog);
|
|
225
265
|
}
|
|
226
266
|
|
|
227
267
|
if (Array.isArray(source)) {
|
|
228
268
|
// source is an array
|
|
229
|
-
return matchArr(source, root, matcher as any,
|
|
269
|
+
return matchArr(source, parent, root, matcher as any, failureLog);
|
|
230
270
|
}
|
|
231
271
|
|
|
232
272
|
// already determined above that the source and matcher are not equal
|
|
233
273
|
|
|
234
|
-
|
|
274
|
+
failureLog?.push(
|
|
235
275
|
`value ${JSON.stringify(
|
|
236
276
|
source
|
|
237
277
|
)} does not match given matcher ${JSON.stringify(matcher)}`
|
|
@@ -245,9 +285,10 @@ function matchEntry<T, C, P, R>(
|
|
|
245
285
|
*/
|
|
246
286
|
function matchArr<T extends any[], C, P, R>(
|
|
247
287
|
source: T,
|
|
288
|
+
parent: P,
|
|
248
289
|
root: R,
|
|
249
290
|
matcher: Match.Arr<T, C, P, R>,
|
|
250
|
-
|
|
291
|
+
failureLog?: Match.FailureLog
|
|
251
292
|
): boolean {
|
|
252
293
|
if (Array.isArray(matcher)) {
|
|
253
294
|
// directly compare array contents
|
|
@@ -256,7 +297,7 @@ function matchArr<T extends any[], C, P, R>(
|
|
|
256
297
|
if (length !== matcher.length) {
|
|
257
298
|
// if lengths not equal, arrays are not equal
|
|
258
299
|
|
|
259
|
-
|
|
300
|
+
failureLog?.push(
|
|
260
301
|
`array lengths are not equal: value length ${source.length} !== matcher length ${matcher.length}`
|
|
261
302
|
);
|
|
262
303
|
|
|
@@ -266,10 +307,12 @@ function matchArr<T extends any[], C, P, R>(
|
|
|
266
307
|
// loop over arrays, matching every value
|
|
267
308
|
let index = -1;
|
|
268
309
|
while (++index < length) {
|
|
269
|
-
if (
|
|
310
|
+
if (
|
|
311
|
+
!matchEntry(source[index], source, root, matcher[index], failureLog)
|
|
312
|
+
) {
|
|
270
313
|
// item did not match, return false
|
|
271
314
|
|
|
272
|
-
|
|
315
|
+
failureLog?.push(
|
|
273
316
|
`index ${index} does not match with value ${JSON.stringify(
|
|
274
317
|
source[index]
|
|
275
318
|
)} and matcher ${matcher[index]}`
|
|
@@ -283,6 +326,81 @@ function matchArr<T extends any[], C, P, R>(
|
|
|
283
326
|
return true;
|
|
284
327
|
}
|
|
285
328
|
|
|
329
|
+
// matcher is plain object
|
|
330
|
+
|
|
331
|
+
if (`every` in matcher) {
|
|
332
|
+
return matchCompound(
|
|
333
|
+
source,
|
|
334
|
+
parent,
|
|
335
|
+
root,
|
|
336
|
+
['every', ...(matcher.every as any)],
|
|
337
|
+
failureLog
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
if (`some` in matcher) {
|
|
341
|
+
return matchCompound(
|
|
342
|
+
source,
|
|
343
|
+
parent,
|
|
344
|
+
root,
|
|
345
|
+
['some', ...(matcher.some as any)],
|
|
346
|
+
failureLog
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
if (`none` in matcher) {
|
|
350
|
+
return matchCompound(
|
|
351
|
+
source,
|
|
352
|
+
parent,
|
|
353
|
+
root,
|
|
354
|
+
['none', ...(matcher.none as any)],
|
|
355
|
+
failureLog
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
if (`single` in matcher) {
|
|
359
|
+
return matchCompound(
|
|
360
|
+
source,
|
|
361
|
+
parent,
|
|
362
|
+
root,
|
|
363
|
+
['single', ...(matcher.single as any)],
|
|
364
|
+
failureLog
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
if (`someItem` in matcher) {
|
|
368
|
+
return matchTraversal(
|
|
369
|
+
source,
|
|
370
|
+
root,
|
|
371
|
+
'someItem',
|
|
372
|
+
matcher.someItem as any,
|
|
373
|
+
failureLog
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
if (`everyItem` in matcher) {
|
|
377
|
+
return matchTraversal(
|
|
378
|
+
source,
|
|
379
|
+
root,
|
|
380
|
+
'everyItem',
|
|
381
|
+
matcher.everyItem as any,
|
|
382
|
+
failureLog
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
if (`noneItem` in matcher) {
|
|
386
|
+
return matchTraversal(
|
|
387
|
+
source,
|
|
388
|
+
root,
|
|
389
|
+
'noneItem',
|
|
390
|
+
matcher.noneItem as any,
|
|
391
|
+
failureLog
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
if (`singleItem` in matcher) {
|
|
395
|
+
return matchTraversal(
|
|
396
|
+
source,
|
|
397
|
+
root,
|
|
398
|
+
'singleItem',
|
|
399
|
+
matcher.singleItem as any,
|
|
400
|
+
failureLog
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
286
404
|
// matcher is plain object with index keys
|
|
287
405
|
|
|
288
406
|
for (const index in matcher as any) {
|
|
@@ -291,7 +409,7 @@ function matchArr<T extends any[], C, P, R>(
|
|
|
291
409
|
if (!(index in source)) {
|
|
292
410
|
// source does not have item at given index
|
|
293
411
|
|
|
294
|
-
|
|
412
|
+
failureLog?.push(
|
|
295
413
|
`index ${index} does not exist in source ${JSON.stringify(
|
|
296
414
|
source
|
|
297
415
|
)} but should match matcher ${JSON.stringify(matcherAtIndex)}`
|
|
@@ -306,13 +424,13 @@ function matchArr<T extends any[], C, P, R>(
|
|
|
306
424
|
source,
|
|
307
425
|
root,
|
|
308
426
|
matcherAtIndex,
|
|
309
|
-
|
|
427
|
+
failureLog
|
|
310
428
|
);
|
|
311
429
|
|
|
312
430
|
if (!result) {
|
|
313
431
|
// item did not match
|
|
314
432
|
|
|
315
|
-
|
|
433
|
+
failureLog?.push(
|
|
316
434
|
`index ${index} does not match with value ${JSON.stringify(
|
|
317
435
|
(source as any)[index]
|
|
318
436
|
)} and matcher ${JSON.stringify(matcherAtIndex)}`
|
|
@@ -335,11 +453,11 @@ function matchPlainObj<T, C, P, R>(
|
|
|
335
453
|
parent: P,
|
|
336
454
|
root: R,
|
|
337
455
|
matcher: Match.Obj<T, C, P, R>,
|
|
338
|
-
|
|
456
|
+
failureLog?: Match.FailureLog
|
|
339
457
|
): boolean {
|
|
340
458
|
if (Array.isArray(matcher)) {
|
|
341
459
|
// the matcher is of compound type
|
|
342
|
-
return matchCompound(source, parent, root, matcher as any,
|
|
460
|
+
return matchCompound(source, parent, root, matcher as any, failureLog);
|
|
343
461
|
}
|
|
344
462
|
|
|
345
463
|
// partial object props matcher
|
|
@@ -348,7 +466,7 @@ function matchPlainObj<T, C, P, R>(
|
|
|
348
466
|
if (!(key in source)) {
|
|
349
467
|
// the source does not have the given key
|
|
350
468
|
|
|
351
|
-
|
|
469
|
+
failureLog?.push(
|
|
352
470
|
`key ${key} is specified in matcher but not present in value ${JSON.stringify(
|
|
353
471
|
source
|
|
354
472
|
)}`
|
|
@@ -363,11 +481,11 @@ function matchPlainObj<T, C, P, R>(
|
|
|
363
481
|
source,
|
|
364
482
|
root,
|
|
365
483
|
matcher[key],
|
|
366
|
-
|
|
484
|
+
failureLog
|
|
367
485
|
);
|
|
368
486
|
|
|
369
487
|
if (!result) {
|
|
370
|
-
|
|
488
|
+
failureLog?.push(
|
|
371
489
|
`key ${key} does not match in value ${JSON.stringify(
|
|
372
490
|
(source as any)[key]
|
|
373
491
|
)} with matcher ${JSON.stringify(matcher[key])}`
|
|
@@ -389,7 +507,7 @@ function matchCompound<T, C, P, R>(
|
|
|
389
507
|
parent: P,
|
|
390
508
|
root: R,
|
|
391
509
|
compound: [Match.CompoundType, ...Match.Entry<T, C, P, R>[]],
|
|
392
|
-
|
|
510
|
+
failureLog?: Match.FailureLog
|
|
393
511
|
): boolean {
|
|
394
512
|
// first item indicates compound match type
|
|
395
513
|
const matchType = compound[0];
|
|
@@ -410,11 +528,11 @@ function matchCompound<T, C, P, R>(
|
|
|
410
528
|
parent,
|
|
411
529
|
root,
|
|
412
530
|
compound[index] as Entry,
|
|
413
|
-
|
|
531
|
+
failureLog
|
|
414
532
|
);
|
|
415
533
|
|
|
416
534
|
if (!result) {
|
|
417
|
-
|
|
535
|
+
failureLog?.push(
|
|
418
536
|
`in compound "every": match at index ${index} failed`
|
|
419
537
|
);
|
|
420
538
|
|
|
@@ -432,11 +550,11 @@ function matchCompound<T, C, P, R>(
|
|
|
432
550
|
parent,
|
|
433
551
|
root,
|
|
434
552
|
compound[index] as Entry,
|
|
435
|
-
|
|
553
|
+
failureLog
|
|
436
554
|
);
|
|
437
555
|
|
|
438
556
|
if (result) {
|
|
439
|
-
|
|
557
|
+
failureLog?.push(
|
|
440
558
|
`in compound "none": match at index ${index} succeeded`
|
|
441
559
|
);
|
|
442
560
|
|
|
@@ -456,12 +574,12 @@ function matchCompound<T, C, P, R>(
|
|
|
456
574
|
parent,
|
|
457
575
|
root,
|
|
458
576
|
compound[index] as Entry,
|
|
459
|
-
|
|
577
|
+
failureLog
|
|
460
578
|
);
|
|
461
579
|
|
|
462
580
|
if (result) {
|
|
463
581
|
if (onePassed) {
|
|
464
|
-
|
|
582
|
+
failureLog?.push(
|
|
465
583
|
`in compound "single": multiple matches succeeded`
|
|
466
584
|
);
|
|
467
585
|
|
|
@@ -473,7 +591,7 @@ function matchCompound<T, C, P, R>(
|
|
|
473
591
|
}
|
|
474
592
|
|
|
475
593
|
if (!onePassed) {
|
|
476
|
-
|
|
594
|
+
failureLog?.push(`in compound "single": no matches succeeded`);
|
|
477
595
|
}
|
|
478
596
|
|
|
479
597
|
return onePassed;
|
|
@@ -486,7 +604,7 @@ function matchCompound<T, C, P, R>(
|
|
|
486
604
|
parent,
|
|
487
605
|
root,
|
|
488
606
|
compound[index] as Entry,
|
|
489
|
-
|
|
607
|
+
failureLog
|
|
490
608
|
);
|
|
491
609
|
|
|
492
610
|
if (result) {
|
|
@@ -494,9 +612,87 @@ function matchCompound<T, C, P, R>(
|
|
|
494
612
|
}
|
|
495
613
|
}
|
|
496
614
|
|
|
497
|
-
|
|
615
|
+
failureLog?.push(`in compound "some": no matches succeeded`);
|
|
616
|
+
|
|
617
|
+
return false;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function matchTraversal<T extends any[], C extends any[], R>(
|
|
623
|
+
source: T,
|
|
624
|
+
root: R,
|
|
625
|
+
matchType: Match.ArrayTraversalType,
|
|
626
|
+
matcher: Match.Entry<T[keyof T], C[keyof C], T, R>,
|
|
627
|
+
failureLog?: Match.FailureLog
|
|
628
|
+
): boolean {
|
|
629
|
+
let index = -1;
|
|
630
|
+
const length = source.length;
|
|
631
|
+
|
|
632
|
+
switch (matchType) {
|
|
633
|
+
case 'someItem': {
|
|
634
|
+
while (++index < length) {
|
|
635
|
+
if (matchEntry(source[index], source, root, matcher, failureLog)) {
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
failureLog?.push(
|
|
641
|
+
`in array traversal "someItem": no items matched given matcher`
|
|
642
|
+
);
|
|
498
643
|
|
|
499
644
|
return false;
|
|
500
645
|
}
|
|
646
|
+
case 'everyItem': {
|
|
647
|
+
while (++index < length) {
|
|
648
|
+
if (!matchEntry(source[index], source, root, matcher, failureLog)) {
|
|
649
|
+
failureLog?.push(
|
|
650
|
+
`in array traversal "everyItem": at least one item did not match given matcher`
|
|
651
|
+
);
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
case 'noneItem': {
|
|
659
|
+
while (++index < length) {
|
|
660
|
+
if (matchEntry(source[index], source, root, matcher, failureLog)) {
|
|
661
|
+
failureLog?.push(
|
|
662
|
+
`in array traversal "noneItem": at least one item matched given matcher`
|
|
663
|
+
);
|
|
664
|
+
return false;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
case 'singleItem': {
|
|
671
|
+
let singleMatched = false;
|
|
672
|
+
|
|
673
|
+
while (++index < length) {
|
|
674
|
+
if (matchEntry(source[index], source, root, matcher, failureLog)) {
|
|
675
|
+
if (singleMatched) {
|
|
676
|
+
failureLog?.push(
|
|
677
|
+
`in array traversal "singleItem": more than one item matched given matcher`
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
singleMatched = true;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (!singleMatched) {
|
|
688
|
+
failureLog?.push(
|
|
689
|
+
`in array traversal "singleItem": no item matched given matcher`
|
|
690
|
+
);
|
|
691
|
+
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return true;
|
|
696
|
+
}
|
|
501
697
|
}
|
|
502
698
|
}
|