aimx/info_library/
collection_cards.rs

1//! Collection function documentation cards.
2//!
3//! Provides comprehensive FunctionCard instances for all 20 collection manipulation
4//! functions in the Aim standard library, including detailed usage examples
5//! and cross-references between related functions.
6
7use super::function_card::{ArgumentInfo, FunctionCard};
8
9/// All collection function documentation cards.
10pub const COLLECTION_CARDS: &[FunctionCard] = &[
11    // count(array) -> f64
12    FunctionCard {
13        identifier: "count",
14        signature: "count(array)",
15        brief: "Count elements in arrays and literals.",
16        description: "Returns the number of elements in an array, 1.0 for any literal value, \
17                     or 0.0 for other types. This function is useful for determining the size \
18                     of collections, checking if a value exists, or counting items in data \
19                     processing pipelines.",
20        arguments: &[
21            &ArgumentInfo {
22                label: "array",
23                description: "Array to count elements in, or any value",
24                type_hint: "Any",
25                optional: false,
26            },
27        ],
28        returns: "Number of elements (f64)",
29        errors: "None - always succeeds",
30        categories: &["collection"],
31        examples: &[
32            r#"count((1, 2, 3, 4, 5)) => 5.0"#,
33            r#"count(("a", "b", "c")) => 3.0"#,
34            r#"count(42) => 1.0"#,
35            r#"count("hello") => 1.0"#,
36        ],
37    },
38    
39    // len(array) -> f64
40    FunctionCard {
41        identifier: "len",
42        signature: "len(array)",
43        brief: "Get length of arrays or text.",
44        description: "Returns the number of elements in an array or the number of characters \
45                     in a text string. For other literals, returns 1.0. For other types, \
46                     returns 0.0. This function is commonly used for validation, iteration \
47                     bounds checking, or determining data size.",
48        arguments: &[
49            &ArgumentInfo {
50                label: "array",
51                description: "Array or text to measure length of",
52                type_hint: "Any",
53                optional: false,
54            },
55        ],
56        returns: "Length of array or text (f64)",
57        errors: "None - always succeeds",
58        categories: &["collection"],
59        examples: &[
60            r#"len((1, 2, 3, 4)) => 4.0"#,
61            r#"len("hello world") => 11.0"#,
62            r#"len(("a", "b", "c")) => 3.0"#,
63            r#"len("") => 0.0"#,
64        ],
65    },
66    
67    // find(array, closure) -> Value
68    FunctionCard {
69        identifier: "find",
70        signature: "find(array, closure)",
71        brief: "Find first array element for which closure evaluates truthy.",
72        description: "Iterates through the array and returns the first element for which the \
73                     closure returns true. If no element matches, returns Empty. This function \
74                     is essential for searching collections, filtering data, or finding \
75                     specific items based on custom criteria.",
76        arguments: &[
77            &ArgumentInfo {
78                label: "array",
79                description: "Array to search through",
80                type_hint: "Array",
81                optional: false,
82            },
83            &ArgumentInfo {
84                label: "closure",
85                description: "Function that returns true for matching elements",
86                type_hint: "Closure",
87                optional: false,
88            },
89        ],
90        returns: "First matching element or Empty",
91        errors: "Error if closure argument is not a function",
92        categories: &["collection", "functional"],
93        examples: &[
94            r#"find((1, 2, 3, 4, 5), x => x > 3) => 4"#,
95            r#"find(("apple", "banana", "cherry"), x => len(x) > 5) => "banana""#,
96            r#"find((1, 2, 3), x => x > 10) => Empty"#,
97        ],
98    },
99    
100    // find_index(array, closure) -> f64
101    FunctionCard {
102        identifier: "find_index",
103        signature: "find_index(array, closure)",
104        brief: "Find index of first array element for which closure evaluates truthy.",
105        description: "Iterates through the array and returns the zero-based index of the \
106                     first element for which the closure returns true. If no element matches, \
107                     returns -1.0. This function is useful for locating items in arrays, \
108                     implementing search functionality, or finding positions for updates.",
109        arguments: &[
110            &ArgumentInfo {
111                label: "array",
112                description: "Array to search through",
113                type_hint: "Array",
114                optional: false,
115            },
116            &ArgumentInfo {
117                label: "closure",
118                description: "Function that returns true for matching elements",
119                type_hint: "Closure",
120                optional: false,
121            },
122        ],
123        returns: "Index of first matching element or -1.0 (f64)",
124        errors: "Error if closure argument is not a function",
125        categories: &["collection", "functional"],
126        examples: &[
127            r#"find_index((1, 2, 3, 4, 5), x => x > 3) => 3.0"#,
128            r#"find_index(("apple", "banana", "cherry"), x => len(x) > 5) => 1.0"#,
129            r#"find_index((1, 2, 3), x => x > 10) => -1.0"#,
130        ],
131    },
132    
133    // flatten(array) -> Array
134    FunctionCard {
135        identifier: "flatten",
136        signature: "flatten(array)",
137        brief: "Flatten one level of nested arrays.",
138        description: "Removes one level of nesting from arrays. Nested arrays are expanded \
139                     and their elements are added to the result at the same level. Non-array \
140                     elements are copied as-is. This function is useful for simplifying \
141                     nested data structures, preparing data for processing, or normalizing \
142                     collection depths.",
143        arguments: &[
144            &ArgumentInfo {
145                label: "array",
146                description: "Array with nested arrays to flatten",
147                type_hint: "Array",
148                optional: false,
149            },
150        ],
151        returns: "Flattened array",
152        errors: "Error if first argument is not an array",
153        categories: &["collection"],
154        examples: &[
155            r#"flatten(((1, 2), (3, 4), (5))) => (1, 2, 3, 4, 5)"#,
156            r#"flatten((1, (2, 3), 4)) => (1, 2, 3, 4)"#,
157            r#"flatten((1, 2, 3)) => (1, 2, 3)"#,
158        ],
159    },
160    
161    // unique(array) -> Array
162    FunctionCard {
163        identifier: "unique",
164        signature: "unique(array)",
165        brief: "Remove duplicate elements from an array, preserving first occurrence order.",
166        description: "Creates a new array with duplicate elements removed. The first \
167                     occurrence of each unique element is preserved, maintaining the \
168                     original order. Uniqueness is determined by comparing string \
169                     representations of values. This function is essential for data \
170                     deduplication, set operations, or cleaning up collections.",
171        arguments: &[
172            &ArgumentInfo {
173                label: "array",
174                description: "Array to remove duplicates from",
175                type_hint: "Array",
176                optional: false,
177            },
178        ],
179        returns: "Array with duplicates removed",
180        errors: "Error if first argument is not an array",
181        categories: &["collection"],
182        examples: &[
183            r#"unique((1, 2, 2, 3, 3, 3)) => (1, 2, 3)"#,
184            r#"unique(("a", "b", "a", "c")) => ("a", "b", "c")"#,
185            r#"unique((1, 2, 3)) => (1, 2, 3)"#,
186        ],
187    },
188    
189    // reverse(array) -> Array
190    FunctionCard {
191        identifier: "reverse",
192        signature: "reverse(array)",
193        brief: "Reverse array elements.",
194        description: "Creates a new array with elements in reverse order. The first element \
195                     becomes the last, the second becomes the second-to-last, and so on. \
196                     This function is useful for reversing iteration order, implementing \
197                     stack-like behavior, or displaying data in reverse sequence.",
198        arguments: &[
199            &ArgumentInfo {
200                label: "array",
201                description: "Array to reverse",
202                type_hint: "Array",
203                optional: false,
204            },
205        ],
206        returns: "Reversed array",
207        errors: "Error if first argument is not an array",
208        categories: &["collection"],
209        examples: &[
210            r#"reverse((1, 2, 3, 4)) => (4, 3, 2, 1)"#,
211            r#"reverse(("a", "b", "c")) => ("c", "b", "a")"#,
212            r#"reverse(()) => ()"#,
213        ],
214    },
215    
216    // take(array, count) -> Array
217    FunctionCard {
218        identifier: "take",
219        signature: "take(array, count)",
220        brief: "Take first N elements from an array.",
221        description: "Creates a new array containing only the first N elements from the \
222                     input array. If N is greater than the array length, returns the \
223                     entire array. If N is zero or negative, returns an empty array. \
224                     This function is useful for pagination, sampling data, or limiting \
225                     results.",
226        arguments: &[
227            &ArgumentInfo {
228                label: "array",
229                description: "Array to take elements from",
230                type_hint: "Array",
231                optional: false,
232            },
233            &ArgumentInfo {
234                label: "count",
235                description: "Number of elements to take from the beginning",
236                type_hint: "f64",
237                optional: false,
238            },
239        ],
240        returns: "Array with first N elements",
241        errors: "Error if count is not a number or array is not an array",
242        categories: &["collection"],
243        examples: &[
244            r#"take((1, 2, 3, 4, 5), 3) => (1, 2, 3)"#,
245            r#"take(("a", "b", "c"), 2) => ("a", "b")"#,
246            r#"take((1, 2, 3), 10) => (1, 2, 3)"#,
247        ],
248    },
249    
250    // take_right(array, count) -> Array
251    FunctionCard {
252        identifier: "take_right",
253        signature: "take_right(array, count)",
254        brief: "Take last N elements from an array.",
255        description: "Creates a new array containing only the last N elements from the \
256                     input array. If N is greater than the array length, returns the \
257                     entire array. If N is zero or negative, returns an empty array. \
258                     This function is useful for getting recent items, implementing \
259                     sliding windows, or accessing tail data.",
260        arguments: &[
261            &ArgumentInfo {
262                label: "array",
263                description: "Array to take elements from",
264                type_hint: "Array",
265                optional: false,
266            },
267            &ArgumentInfo {
268                label: "count",
269                description: "Number of elements to take from the end",
270                type_hint: "f64",
271                optional: false,
272            },
273        ],
274        returns: "Array with last N elements",
275        errors: "Error if count is not a number or array is not an array",
276        categories: &["collection"],
277        examples: &[
278            r#"take_right((1, 2, 3, 4, 5), 3) => (3, 4, 5)"#,
279            r#"take_right(("a", "b", "c"), 2) => ("b", "c")"#,
280            r#"take_right((1, 2, 3), 10) => (1, 2, 3)"#,
281        ],
282    },
283    
284    // skip(array, count) -> Array
285    FunctionCard {
286        identifier: "skip",
287        signature: "skip(array, count)",
288        brief: "Skip first N elements of an array.",
289        description: "Creates a new array with the first N elements removed. If N is greater \
290                     than or equal to the array length, returns an empty array. If N is zero \
291                     or negative, returns the entire array. This function is useful for \
292                     pagination, skipping headers, or ignoring initial data.",
293        arguments: &[
294            &ArgumentInfo {
295                label: "array",
296                description: "Array to skip elements from",
297                type_hint: "Array",
298                optional: false,
299            },
300            &ArgumentInfo {
301                label: "count",
302                description: "Number of elements to skip from the beginning",
303                type_hint: "f64",
304                optional: false,
305            },
306        ],
307        returns: "Array with first N elements removed",
308        errors: "Error if count is not a number or array is not an array",
309        categories: &["collection"],
310        examples: &[
311            r#"skip((1, 2, 3, 4, 5), 2) => (3, 4, 5)"#,
312            r#"skip(("a", "b", "c"), 1) => ("b", "c")"#,
313            r#"skip((1, 2, 3), 10) => ()"#,
314        ],
315    },
316    
317    // skip_right(array, count) -> Array
318    FunctionCard {
319        identifier: "skip_right",
320        signature: "skip_right(array, count)",
321        brief: "Skip last N elements of an array.",
322        description: "Creates a new array with the last N elements removed. If N is greater \
323                     than or equal to the array length, returns an empty array. If N is zero \
324                     or negative, returns the entire array. This function is useful for \
325                     removing footers, skipping trailing data, or implementing reverse \
326                     pagination.",
327        arguments: &[
328            &ArgumentInfo {
329                label: "array",
330                description: "Array to skip elements from",
331                type_hint: "Array",
332                optional: false,
333            },
334            &ArgumentInfo {
335                label: "count",
336                description: "Number of elements to skip from the end",
337                type_hint: "f64",
338                optional: false,
339            },
340        ],
341        returns: "Array with last N elements removed",
342        errors: "Error if count is not a number or array is not an array",
343        categories: &["collection"],
344        examples: &[
345            r#"skip_right((1, 2, 3, 4, 5), 2) => (1, 2, 3)"#,
346            r#"skip_right(("a", "b", "c"), 1) => ("a", "b")"#,
347            r#"skip_right((1, 2, 3), 10) => ()"#,
348        ],
349    },
350    
351    // chunk(array, size) -> Array
352    FunctionCard {
353        identifier: "chunk",
354        signature: "chunk(array, size)",
355        brief: "Split array into chunks of fixed size.",
356        description: "Divides an array into smaller arrays (chunks) of the specified size. \
357                     The last chunk may contain fewer elements if the array length is not \
358                     evenly divisible by the chunk size. This function is useful for \
359                     batch processing, pagination, or parallel processing of large datasets.",
360        arguments: &[
361            &ArgumentInfo {
362                label: "array",
363                description: "Array to split into chunks",
364                type_hint: "Array",
365                optional: false,
366            },
367            &ArgumentInfo {
368                label: "size",
369                description: "Size of each chunk (must be > 0)",
370                type_hint: "f64",
371                optional: false,
372            },
373        ],
374        returns: "Array of chunked arrays",
375        errors: "Error if size is zero, not a number, or array is not an array",
376        categories: &["collection"],
377        examples: &[
378            r#"chunk((1, 2, 3, 4, 5, 6), 2) => ((1, 2), (3, 4), (5, 6))"#,
379            r#"chunk(("a", "b", "c", "d"), 3) => (("a", "b", "c"), ("d",))"#,
380            r#"chunk((1, 2, 3), 5) => ((1, 2, 3),)"#,
381        ],
382    },
383    
384    // group_by(array, closure) -> Array
385    FunctionCard {
386        identifier: "group_by",
387        signature: "group_by(array, closure)",
388        brief: "Group array elements by key from closure.",
389        description: "Groups array elements by the result of applying the closure to each \
390                     element. Returns an array of (key, group) pairs where each group is \
391                     an array of elements that produced the same key. Keys are determined \
392                     by the string representation of the closure result. This function is \
393                     essential for data aggregation, categorization, or organizing data \
394                     by common attributes.",
395        arguments: &[
396            &ArgumentInfo {
397                label: "array",
398                description: "Array to group elements from",
399                type_hint: "Array",
400                optional: false,
401            },
402            &ArgumentInfo {
403                label: "closure",
404                description: "Function that returns grouping key for each element",
405                type_hint: "Closure",
406                optional: false,
407            },
408        ],
409        returns: "Array of (key, group) pairs",
410        errors: "Error if closure argument is not a function",
411        categories: &["collection", "functional"],
412        examples: &[
413            r#"group_by((1, 2, 3, 4, 5), x => x % 2) => (("1.0", (1, 3, 5)), ("0.0", (2, 4)))"#,
414            r#"group_by(("apple", "banana", "cherry"), x => len(x)) => (("5.0", ("apple",)), ("6.0", ("banana", "cherry")))"#,
415            r#"group_by((1, 1, 2, 2, 3), x => x) => (("1.0", (1, 1)), ("2.0", (2, 2)), ("3.0", (3,)))"#,
416        ],
417    },
418    
419    // partition(array, closure) -> Array
420    FunctionCard {
421        identifier: "partition",
422        signature: "partition(array, closure)",
423        brief: "Partition array into (true_items, false_items) using closure predicate.",
424        description: "Splits an array into two groups based on the result of the closure \
425                     predicate. Elements for which the closure returns true are placed in \
426                     the first group, and elements for which it returns false are placed \
427                     in the second group. This function is useful for filtering data, \
428                     separating items by criteria, or implementing conditional logic.",
429        arguments: &[
430            &ArgumentInfo {
431                label: "array",
432                description: "Array to partition",
433                type_hint: "Array",
434                optional: false,
435            },
436            &ArgumentInfo {
437                label: "closure",
438                description: "Predicate function that returns true or false for each element",
439                type_hint: "Closure",
440                optional: false,
441            },
442        ],
443        returns: "Array containing (true_items, false_items)",
444        errors: "Error if closure argument is not a function",
445        categories: &["collection", "functional"],
446        examples: &[
447            r#"partition((1, 2, 3, 4, 5), x => x % 2 == 0) => ((2, 4), (1, 3, 5))"#,
448            r#"partition(("apple", "banana", "cherry"), x => len(x) > 5) => (("banana", "cherry"), ("apple",))"#,
449            r#"partition((1, 2, 3), x => x > 10) => ((), (1, 2, 3))"#,
450        ],
451    },
452    
453    // sort_by(array, closure) -> Array
454    FunctionCard {
455        identifier: "sort_by",
456        signature: "sort_by(array, closure)",
457        brief: "Sort array by key from closure.",
458        description: "Sorts array elements based on the keys produced by applying the closure \
459                     to each element. Keys are compared using their string representations, \
460                     which provides a consistent ordering for mixed types. This function is \
461                     useful for custom sorting, organizing data by computed values, or \
462                     implementing complex ordering logic.",
463        arguments: &[
464            &ArgumentInfo {
465                label: "array",
466                description: "Array to sort",
467                type_hint: "Array",
468                optional: false,
469            },
470            &ArgumentInfo {
471                label: "closure",
472                description: "Function that returns sort key for each element",
473                type_hint: "Closure",
474                optional: false,
475            },
476        ],
477        returns: "Sorted array",
478        errors: "Error if closure argument is not a function",
479        categories: &["collection", "functional"],
480        examples: &[
481            r#"sort_by((3, 1, 4, 1, 5), x => x) => (1, 1, 3, 4, 5)"#,
482            r#"sort_by(("cherry", "apple", "banana"), x => len(x)) => ("apple", "banana", "cherry")"#,
483            r#"sort_by((("b", 2), ("a", 1), ("c", 3)), x => x[1]) => (("a", 1), ("b", 2), ("c", 3))"#,
484        ],
485    },
486    
487    // all_unique(array) -> bool
488    FunctionCard {
489        identifier: "all_unique",
490        signature: "all_unique(array)",
491        brief: "True if all elements are unique.",
492        description: "Checks whether all elements in the array are unique. Returns true if \
493                     no duplicates exist, false otherwise. For empty arrays, returns false. \
494                     Uniqueness is determined by comparing string representations of values. \
495                     This function is useful for data validation, checking for duplicates, \
496                     or ensuring set-like properties.",
497        arguments: &[
498            &ArgumentInfo {
499                label: "array",
500                description: "Array to check for uniqueness",
501                type_hint: "Array",
502                optional: false,
503            },
504        ],
505        returns: "Boolean indicating if all elements are unique",
506        errors: "Error if first argument is not an array",
507        categories: &["collection"],
508        examples: &[
509            r#"all_unique((1, 2, 3, 4)) => true"#,
510            r#"all_unique((1, 2, 2, 3)) => false"#,
511            r#"all_unique(("a", "b", "c")) => true"#,
512            r#"all_unique(()) => false"#,
513        ],
514    },
515    
516    // take_while(array, closure) -> Array
517    FunctionCard {
518        identifier: "take_while",
519        signature: "take_while(array, closure)",
520        brief: "Take elements while closure predicate is truthy.",
521        description: "Creates a new array containing elements from the beginning of the input \
522                     array while the closure returns true for each element. As soon as the \
523                     closure returns false for an element, processing stops and no further \
524                     elements are included. This function is useful for taking prefixes of \
525                     data, implementing conditional extraction, or processing data until \
526                     a condition changes.",
527        arguments: &[
528            &ArgumentInfo {
529                label: "array",
530                description: "Array to take elements from",
531                type_hint: "Array",
532                optional: false,
533            },
534            &ArgumentInfo {
535                label: "closure",
536                description: "Predicate function that determines when to stop taking elements",
537                type_hint: "Closure",
538                optional: false,
539            },
540        ],
541        returns: "Array with elements taken while predicate is true",
542        errors: "Error if closure argument is not a function",
543        categories: &["collection", "functional"],
544        examples: &[
545            r#"take_while((1, 2, 3, 4, 5), x => x < 4) => (1, 2, 3)"#,
546            r#"take_while(("a", "bb", "ccc", "dd"), x => len(x) <= 2) => ("a", "bb")"#,
547            r#"take_while((1, 2, 3), x => x > 10) => ()"#,
548        ],
549    },
550    
551    // skip_while(array, closure) -> Array
552    FunctionCard {
553        identifier: "skip_while",
554        signature: "skip_while(array, closure)",
555        brief: "Skip elements while closure predicate is truthy.",
556        description: "Creates a new array with elements from the input array, starting from \
557                     the first element for which the closure returns false. All elements \
558                     before this point (where closure returns true) are skipped. This \
559                     function is useful for skipping headers, ignoring initial data that \
560                     meets certain criteria, or finding the first element that doesn't \
561                     match a condition.",
562        arguments: &[
563            &ArgumentInfo {
564                label: "array",
565                description: "Array to skip elements from",
566                type_hint: "Array",
567                optional: false,
568            },
569            &ArgumentInfo {
570                label: "closure",
571                description: "Predicate function that determines when to stop skipping elements",
572                type_hint: "Closure",
573                optional: false,
574            },
575        ],
576        returns: "Array with elements after predicate becomes false",
577        errors: "Error if closure argument is not a function",
578        categories: &["collection", "functional"],
579        examples: &[
580            r#"skip_while((1, 2, 3, 4, 5), x => x < 4) => (4, 5)"#,
581            r#"skip_while(("a", "bb", "ccc", "dd"), x => len(x) <= 2) => ("ccc", "dd")"#,
582            r#"skip_while((1, 2, 3), x => x > 10) => (1, 2, 3)"#,
583        ],
584    },
585    
586    // zip(array1, array2) -> Array
587    FunctionCard {
588        identifier: "zip",
589        signature: "zip(array1, array2)",
590        brief: "Zip two arrays into array of 2-element arrays.",
591        description: "Combines two arrays by pairing elements at corresponding positions. \
592                     The resulting array contains pairs where the first element comes from \
593                     the first array and the second element comes from the second array. \
594                     The length of the result is the minimum of the two input arrays. This \
595                     function is useful for combining related data, creating coordinate \
596                     pairs, or processing parallel arrays.",
597        arguments: &[
598            &ArgumentInfo {
599                label: "array1",
600                description: "First array to zip",
601                type_hint: "Array",
602                optional: false,
603            },
604            &ArgumentInfo {
605                label: "array2",
606                description: "Second array to zip",
607                type_hint: "Array",
608                optional: false,
609            },
610        ],
611        returns: "Array of paired elements",
612        errors: "Error if either argument is not an array",
613        categories: &["collection"],
614        examples: &[
615            r#"zip((1, 2, 3), ("a", "b", "c")) => ((1, "a"), (2, "b"), (3, "c"))"#,
616            r#"zip((1, 2), ("x", "y", "z")) => ((1, "x"), (2, "y"))"#,
617            r#"zip((), ("a", "b")) => ()"#,
618        ],
619    },
620    
621    // unzip(array) -> Array
622    FunctionCard {
623        identifier: "unzip",
624        signature: "unzip(array)",
625        brief: "Unzip array of 2-element arrays into (first_items, second_items).",
626        description: "Reverses the zip operation by separating an array of pairs into two \
627                     separate arrays. The first resulting array contains all the first \
628                     elements from each pair, and the second resulting array contains all \
629                     the second elements. This function is useful for decomposing paired \
630                     data, separating coordinates, or undoing zip operations.",
631        arguments: &[
632            &ArgumentInfo {
633                label: "array",
634                description: "Array of 2-element arrays to unzip",
635                type_hint: "Array",
636                optional: false,
637            },
638        ],
639        returns: "Array containing (first_items, second_items)",
640        errors: "Error if input is not an array or contains non-pair elements",
641        categories: &["collection"],
642        examples: &[
643            r#"unzip(((1, "a"), (2, "b"), (3, "c"))) => ((1, 2, 3), ("a", "b", "c"))"#,
644            r#"unzip(((1, 2), (3, 4))) => ((1, 3), (2, 4))"#,
645            r#"unzip(()) => ((), ())"#,
646        ],
647    },
648];