rs_web/lua/
types.rs

1//! Lua API type definitions for EmmyLua annotations
2
3/// A Lua function definition
4#[derive(Debug, Clone)]
5pub struct LuaFunction {
6    pub name: &'static str,
7    pub module: Option<&'static str>,
8    pub description: &'static str,
9    pub params: &'static [LuaParam],
10    pub returns: &'static str,
11    /// For generic return types like AsyncIOTask<T>, specifies what T is
12    pub generic_return: Option<&'static str>,
13}
14
15/// A Lua function parameter
16#[derive(Debug, Clone)]
17pub struct LuaParam {
18    pub name: &'static str,
19    pub typ: &'static str,
20    pub description: &'static str,
21    pub optional: bool,
22}
23
24/// A Lua class/table type definition
25#[derive(Debug, Clone)]
26pub struct LuaClass {
27    pub name: &'static str,
28    pub description: &'static str,
29    pub fields: &'static [LuaField],
30    /// Whether this class is generic (e.g., AsyncIOTask<T>)
31    pub is_generic: bool,
32}
33
34/// A field in a Lua class
35#[derive(Debug, Clone)]
36pub struct LuaField {
37    pub name: &'static str,
38    pub typ: &'static str,
39    pub description: &'static str,
40}
41
42// ============================================================================
43// CLASS DEFINITIONS
44// ============================================================================
45
46pub static LUA_CLASSES: &[LuaClass] = &[
47    LuaClass {
48        name: "AsyncTask",
49        description: "Async task handle for fetch operations",
50        is_generic: true,
51        fields: &[LuaField {
52            name: "is_completed",
53            typ: "fun(): boolean",
54            description: "Check if task is completed",
55        }],
56    },
57    LuaClass {
58        name: "AsyncIOTask",
59        description: "Async task handle for I/O operations",
60        is_generic: true,
61        fields: &[LuaField {
62            name: "is_completed",
63            typ: "fun(): boolean",
64            description: "Check if task is completed",
65        }],
66    },
67    LuaClass {
68        name: "AsyncLuaTask",
69        description: "Async task handle for wrapped Lua functions",
70        is_generic: true,
71        fields: &[LuaField {
72            name: "is_completed",
73            typ: "fun(): boolean",
74            description: "Check if task is completed",
75        }],
76    },
77    LuaClass {
78        name: "FetchResponse",
79        description: "HTTP response from fetch operations",
80        is_generic: false,
81        fields: &[
82            LuaField {
83                name: "status",
84                typ: "number",
85                description: "HTTP status code",
86            },
87            LuaField {
88                name: "ok",
89                typ: "boolean",
90                description: "True if status is 2xx",
91            },
92            LuaField {
93                name: "body",
94                typ: "string",
95                description: "Response body",
96            },
97            LuaField {
98                name: "headers",
99                typ: "table<string, string>",
100                description: "Response headers",
101            },
102            LuaField {
103                name: "json",
104                typ: "fun(): any",
105                description: "Parse body as JSON",
106            },
107        ],
108    },
109    LuaClass {
110        name: "FileMetadata",
111        description: "File metadata from async.metadata",
112        is_generic: false,
113        fields: &[
114            LuaField {
115                name: "is_file",
116                typ: "boolean",
117                description: "True if path is a file",
118            },
119            LuaField {
120                name: "is_dir",
121                typ: "boolean",
122                description: "True if path is a directory",
123            },
124            LuaField {
125                name: "len",
126                typ: "number",
127                description: "File size in bytes",
128            },
129            LuaField {
130                name: "readonly",
131                typ: "boolean",
132                description: "True if file is read-only",
133            },
134            LuaField {
135                name: "modified",
136                typ: "number?",
137                description: "Unix timestamp of last modification",
138            },
139        ],
140    },
141    LuaClass {
142        name: "DirEntry",
143        description: "Directory entry from async.read_dir",
144        is_generic: false,
145        fields: &[
146            LuaField {
147                name: "path",
148                typ: "string",
149                description: "Full path to entry",
150            },
151            LuaField {
152                name: "name",
153                typ: "string",
154                description: "Entry name",
155            },
156            LuaField {
157                name: "is_file",
158                typ: "boolean",
159                description: "True if entry is a file",
160            },
161            LuaField {
162                name: "is_dir",
163                typ: "boolean",
164                description: "True if entry is a directory",
165            },
166            LuaField {
167                name: "is_symlink",
168                typ: "boolean",
169                description: "True if entry is a symlink",
170            },
171        ],
172    },
173    LuaClass {
174        name: "FileInfo",
175        description: "File metadata",
176        is_generic: false,
177        fields: &[
178            LuaField {
179                name: "path",
180                typ: "string",
181                description: "Absolute path",
182            },
183            LuaField {
184                name: "name",
185                typ: "string",
186                description: "Full filename with extension",
187            },
188            LuaField {
189                name: "stem",
190                typ: "string",
191                description: "Filename without extension",
192            },
193            LuaField {
194                name: "ext",
195                typ: "string",
196                description: "File extension",
197            },
198            LuaField {
199                name: "is_dir",
200                typ: "boolean",
201                description: "Whether this is a directory",
202            },
203            LuaField {
204                name: "modified",
205                typ: "number|nil",
206                description: "Unix timestamp of last modification",
207            },
208        ],
209    },
210    LuaClass {
211        name: "FrontmatterResult",
212        description: "Result of reading frontmatter from a file. Frontmatter fields are merged to top level.",
213        is_generic: false,
214        fields: &[
215            LuaField {
216                name: "raw",
217                typ: "string",
218                description: "Original file content",
219            },
220            LuaField {
221                name: "content",
222                typ: "string",
223                description: "Content after frontmatter",
224            },
225            LuaField {
226                name: "[string]",
227                typ: "any",
228                description: "Additional frontmatter fields",
229            },
230        ],
231    },
232    LuaClass {
233        name: "GitInfo",
234        description: "Git repository/file information",
235        is_generic: false,
236        fields: &[
237            LuaField {
238                name: "hash",
239                typ: "string",
240                description: "Full commit hash",
241            },
242            LuaField {
243                name: "short_hash",
244                typ: "string",
245                description: "Short commit hash (7 chars)",
246            },
247            LuaField {
248                name: "timestamp",
249                typ: "number",
250                description: "Commit timestamp (Unix seconds)",
251            },
252            LuaField {
253                name: "author",
254                typ: "string?",
255                description: "Commit author (for file commits)",
256            },
257            LuaField {
258                name: "branch",
259                typ: "string?",
260                description: "Current branch (for repo info)",
261            },
262            LuaField {
263                name: "dirty",
264                typ: "boolean?",
265                description: "Whether repo has uncommitted changes",
266            },
267        ],
268    },
269    LuaClass {
270        name: "ImageDimensions",
271        description: "Image dimensions",
272        is_generic: false,
273        fields: &[
274            LuaField {
275                name: "width",
276                typ: "number",
277                description: "Width in pixels",
278            },
279            LuaField {
280                name: "height",
281                typ: "number",
282                description: "Height in pixels",
283            },
284        ],
285    },
286    LuaClass {
287        name: "DateTime",
288        description: "Date and time components",
289        is_generic: false,
290        fields: &[
291            LuaField {
292                name: "year",
293                typ: "number",
294                description: "Year (e.g., 2024)",
295            },
296            LuaField {
297                name: "month",
298                typ: "number",
299                description: "Month (1-12)",
300            },
301            LuaField {
302                name: "day",
303                typ: "number",
304                description: "Day of month (1-31)",
305            },
306            LuaField {
307                name: "hour",
308                typ: "number",
309                description: "Hour (0-23)",
310            },
311            LuaField {
312                name: "min",
313                typ: "number",
314                description: "Minute (0-59)",
315            },
316            LuaField {
317                name: "sec",
318                typ: "number",
319                description: "Second (0-59)",
320            },
321            LuaField {
322                name: "weekday",
323                typ: "number",
324                description: "Day of week (1=Monday, 7=Sunday)",
325            },
326            LuaField {
327                name: "yday",
328                typ: "number",
329                description: "Day of year (1-366)",
330            },
331        ],
332    },
333];
334
335// ============================================================================
336// FUNCTION DEFINITIONS
337// ============================================================================
338
339pub static LUA_FUNCTIONS: &[LuaFunction] = &[
340    // ========================================================================
341    // rs.ops - Collection Operations
342    // ========================================================================
343    LuaFunction {
344        name: "map",
345        module: Some("ops"),
346        description: "Transform each item using function",
347        params: &[
348            LuaParam {
349                name: "items",
350                typ: "T[]",
351                description: "Items to transform",
352                optional: false,
353            },
354            LuaParam {
355                name: "fn",
356                typ: "fun(item: T): U",
357                description: "Transform function",
358                optional: false,
359            },
360        ],
361        returns: "U[]",
362        generic_return: None,
363    },
364    LuaFunction {
365        name: "filter",
366        module: Some("ops"),
367        description: "Filter items using predicate function",
368        params: &[
369            LuaParam {
370                name: "items",
371                typ: "T[]",
372                description: "Items to filter",
373                optional: false,
374            },
375            LuaParam {
376                name: "fn",
377                typ: "fun(item: T): boolean",
378                description: "Predicate function",
379                optional: false,
380            },
381        ],
382        returns: "T[]",
383        generic_return: None,
384    },
385    LuaFunction {
386        name: "sort",
387        module: Some("ops"),
388        description: "Sort items using comparator function",
389        params: &[
390            LuaParam {
391                name: "items",
392                typ: "T[]",
393                description: "Items to sort",
394                optional: false,
395            },
396            LuaParam {
397                name: "fn",
398                typ: "fun(a: T, b: T): boolean",
399                description: "Comparator (true if a < b)",
400                optional: false,
401            },
402        ],
403        returns: "T[]",
404        generic_return: None,
405    },
406    LuaFunction {
407        name: "find",
408        module: Some("ops"),
409        description: "Find first item matching predicate",
410        params: &[
411            LuaParam {
412                name: "items",
413                typ: "T[]",
414                description: "Items to search",
415                optional: false,
416            },
417            LuaParam {
418                name: "fn",
419                typ: "fun(item: T): boolean",
420                description: "Predicate function",
421                optional: false,
422            },
423        ],
424        returns: "T|nil",
425        generic_return: None,
426    },
427    LuaFunction {
428        name: "group_by",
429        module: Some("ops"),
430        description: "Group items by key returned by function",
431        params: &[
432            LuaParam {
433                name: "items",
434                typ: "T[]",
435                description: "Items to group",
436                optional: false,
437            },
438            LuaParam {
439                name: "fn",
440                typ: "fun(item: T): string",
441                description: "Key function",
442                optional: false,
443            },
444        ],
445        returns: "table<string, T[]>",
446        generic_return: None,
447    },
448    LuaFunction {
449        name: "unique",
450        module: Some("ops"),
451        description: "Remove duplicate items",
452        params: &[LuaParam {
453            name: "items",
454            typ: "T[]",
455            description: "Items to deduplicate",
456            optional: false,
457        }],
458        returns: "T[]",
459        generic_return: None,
460    },
461    LuaFunction {
462        name: "reverse",
463        module: Some("ops"),
464        description: "Reverse array order",
465        params: &[LuaParam {
466            name: "items",
467            typ: "T[]",
468            description: "Items to reverse",
469            optional: false,
470        }],
471        returns: "T[]",
472        generic_return: None,
473    },
474    LuaFunction {
475        name: "take",
476        module: Some("ops"),
477        description: "Take first n items",
478        params: &[
479            LuaParam {
480                name: "items",
481                typ: "T[]",
482                description: "Items",
483                optional: false,
484            },
485            LuaParam {
486                name: "n",
487                typ: "number",
488                description: "Number of items to take",
489                optional: false,
490            },
491        ],
492        returns: "T[]",
493        generic_return: None,
494    },
495    LuaFunction {
496        name: "skip",
497        module: Some("ops"),
498        description: "Skip first n items",
499        params: &[
500            LuaParam {
501                name: "items",
502                typ: "T[]",
503                description: "Items",
504                optional: false,
505            },
506            LuaParam {
507                name: "n",
508                typ: "number",
509                description: "Number of items to skip",
510                optional: false,
511            },
512        ],
513        returns: "T[]",
514        generic_return: None,
515    },
516    LuaFunction {
517        name: "keys",
518        module: Some("ops"),
519        description: "Get all keys from a table",
520        params: &[LuaParam {
521            name: "table",
522            typ: "table",
523            description: "Table to get keys from",
524            optional: false,
525        }],
526        returns: "any[]",
527        generic_return: None,
528    },
529    LuaFunction {
530        name: "values",
531        module: Some("ops"),
532        description: "Get all values from a table",
533        params: &[LuaParam {
534            name: "table",
535            typ: "table",
536            description: "Table to get values from",
537            optional: false,
538        }],
539        returns: "any[]",
540        generic_return: None,
541    },
542    LuaFunction {
543        name: "reduce",
544        module: Some("ops"),
545        description: "Reduce items to single value",
546        params: &[
547            LuaParam {
548                name: "items",
549                typ: "T[]",
550                description: "Items to reduce",
551                optional: false,
552            },
553            LuaParam {
554                name: "initial",
555                typ: "U",
556                description: "Initial accumulator value",
557                optional: false,
558            },
559            LuaParam {
560                name: "fn",
561                typ: "fun(acc: U, item: T): U",
562                description: "Reducer function",
563                optional: false,
564            },
565        ],
566        returns: "U",
567        generic_return: None,
568    },
569    // rs.ops.par - Parallel Collection Operations
570    LuaFunction {
571        name: "map",
572        module: Some("ops.par"),
573        description: "Parallel map with optional context",
574        params: &[
575            LuaParam {
576                name: "items",
577                typ: "T[]",
578                description: "Items to transform",
579                optional: false,
580            },
581            LuaParam {
582                name: "fn",
583                typ: "fun(item: T, ctx: table?): U",
584                description: "Transform function",
585                optional: false,
586            },
587            LuaParam {
588                name: "ctx",
589                typ: "table",
590                description: "Context passed to each call",
591                optional: true,
592            },
593        ],
594        returns: "U[]",
595        generic_return: None,
596    },
597    LuaFunction {
598        name: "filter",
599        module: Some("ops.par"),
600        description: "Parallel filter with optional context",
601        params: &[
602            LuaParam {
603                name: "items",
604                typ: "T[]",
605                description: "Items to filter",
606                optional: false,
607            },
608            LuaParam {
609                name: "fn",
610                typ: "fun(item: T, ctx: table?): boolean",
611                description: "Predicate function",
612                optional: false,
613            },
614            LuaParam {
615                name: "ctx",
616                typ: "table",
617                description: "Context passed to each call",
618                optional: true,
619            },
620        ],
621        returns: "T[]",
622        generic_return: None,
623    },
624    // ========================================================================
625    // rs.fs - File System Operations
626    // ========================================================================
627    LuaFunction {
628        name: "read",
629        module: Some("fs"),
630        description: "Read file contents as string",
631        params: &[LuaParam {
632            name: "path",
633            typ: "string",
634            description: "Path to file",
635            optional: false,
636        }],
637        returns: "string|nil",
638        generic_return: None,
639    },
640    LuaFunction {
641        name: "write",
642        module: Some("fs"),
643        description: "Write content to file",
644        params: &[
645            LuaParam {
646                name: "path",
647                typ: "string",
648                description: "Path to write to",
649                optional: false,
650            },
651            LuaParam {
652                name: "content",
653                typ: "string",
654                description: "Content to write",
655                optional: false,
656            },
657        ],
658        returns: "boolean",
659        generic_return: None,
660    },
661    LuaFunction {
662        name: "copy",
663        module: Some("fs"),
664        description: "Copy a file (works with binary files)",
665        params: &[
666            LuaParam {
667                name: "src",
668                typ: "string",
669                description: "Source file path",
670                optional: false,
671            },
672            LuaParam {
673                name: "dest",
674                typ: "string",
675                description: "Destination file path",
676                optional: false,
677            },
678        ],
679        returns: "boolean",
680        generic_return: None,
681    },
682    LuaFunction {
683        name: "exists",
684        module: Some("fs"),
685        description: "Check if file exists",
686        params: &[LuaParam {
687            name: "path",
688            typ: "string",
689            description: "Path to check",
690            optional: false,
691        }],
692        returns: "boolean",
693        generic_return: None,
694    },
695    LuaFunction {
696        name: "list",
697        module: Some("fs"),
698        description: "List files in directory matching pattern",
699        params: &[
700            LuaParam {
701                name: "path",
702                typ: "string",
703                description: "Directory to search",
704                optional: false,
705            },
706            LuaParam {
707                name: "pattern",
708                typ: "string",
709                description: "Glob pattern (default: '*')",
710                optional: true,
711            },
712        ],
713        returns: "FileInfo[]",
714        generic_return: None,
715    },
716    LuaFunction {
717        name: "list_dirs",
718        module: Some("fs"),
719        description: "List subdirectories",
720        params: &[LuaParam {
721            name: "path",
722            typ: "string",
723            description: "Directory to search",
724            optional: false,
725        }],
726        returns: "string[]",
727        generic_return: None,
728    },
729    LuaFunction {
730        name: "glob",
731        module: Some("fs"),
732        description: "Find files matching glob pattern",
733        params: &[LuaParam {
734            name: "pattern",
735            typ: "string",
736            description: "Glob pattern (e.g., '**/*.md')",
737            optional: false,
738        }],
739        returns: "FileInfo[]",
740        generic_return: None,
741    },
742    LuaFunction {
743        name: "scan",
744        module: Some("fs"),
745        description: "List directories in path",
746        params: &[LuaParam {
747            name: "path",
748            typ: "string",
749            description: "Directory to scan",
750            optional: false,
751        }],
752        returns: "FileInfo[]",
753        generic_return: None,
754    },
755    // rs.fs.par - Parallel File Operations
756    LuaFunction {
757        name: "read",
758        module: Some("fs.par"),
759        description: "Read multiple files in parallel",
760        params: &[LuaParam {
761            name: "paths",
762            typ: "string[]",
763            description: "Paths to read",
764            optional: false,
765        }],
766        returns: "(string|nil)[]",
767        generic_return: None,
768    },
769    LuaFunction {
770        name: "exists",
771        module: Some("fs.par"),
772        description: "Check multiple files exist in parallel",
773        params: &[LuaParam {
774            name: "paths",
775            typ: "string[]",
776            description: "Paths to check",
777            optional: false,
778        }],
779        returns: "boolean[]",
780        generic_return: None,
781    },
782    LuaFunction {
783        name: "copy",
784        module: Some("fs.par"),
785        description: "Copy multiple files in parallel",
786        params: &[
787            LuaParam {
788                name: "sources",
789                typ: "string[]",
790                description: "Source paths",
791                optional: false,
792            },
793            LuaParam {
794                name: "dests",
795                typ: "string[]",
796                description: "Destination paths",
797                optional: false,
798            },
799        ],
800        returns: "(boolean|string)[]",
801        generic_return: None,
802    },
803    LuaFunction {
804        name: "create_dirs",
805        module: Some("fs.par"),
806        description: "Create multiple directories in parallel",
807        params: &[LuaParam {
808            name: "paths",
809            typ: "string[]",
810            description: "Directory paths to create",
811            optional: false,
812        }],
813        returns: "(boolean|string)[]",
814        generic_return: None,
815    },
816    // ========================================================================
817    // rs.data - Data Loading
818    // ========================================================================
819    LuaFunction {
820        name: "load_json",
821        module: Some("data"),
822        description: "Load and parse JSON file",
823        params: &[LuaParam {
824            name: "path",
825            typ: "string",
826            description: "Path to JSON file",
827            optional: false,
828        }],
829        returns: "table|nil",
830        generic_return: None,
831    },
832    LuaFunction {
833        name: "load_yaml",
834        module: Some("data"),
835        description: "Load and parse YAML file",
836        params: &[LuaParam {
837            name: "path",
838            typ: "string",
839            description: "Path to YAML file",
840            optional: false,
841        }],
842        returns: "table|nil",
843        generic_return: None,
844    },
845    LuaFunction {
846        name: "load_toml",
847        module: Some("data"),
848        description: "Load and parse TOML file",
849        params: &[LuaParam {
850            name: "path",
851            typ: "string",
852            description: "Path to TOML file",
853            optional: false,
854        }],
855        returns: "table|nil",
856        generic_return: None,
857    },
858    LuaFunction {
859        name: "load_frontmatter",
860        module: Some("data"),
861        description: "Read and parse frontmatter from markdown file",
862        params: &[LuaParam {
863            name: "path",
864            typ: "string",
865            description: "Path to markdown file",
866            optional: false,
867        }],
868        returns: "FrontmatterResult|nil",
869        generic_return: None,
870    },
871    LuaFunction {
872        name: "from_json",
873        module: Some("data"),
874        description: "Parse JSON string to Lua value",
875        params: &[LuaParam {
876            name: "str",
877            typ: "string",
878            description: "JSON string",
879            optional: false,
880        }],
881        returns: "any",
882        generic_return: None,
883    },
884    LuaFunction {
885        name: "to_json",
886        module: Some("data"),
887        description: "Serialize Lua value to JSON string",
888        params: &[
889            LuaParam {
890                name: "value",
891                typ: "any",
892                description: "Value to serialize",
893                optional: false,
894            },
895            LuaParam {
896                name: "pretty",
897                typ: "boolean",
898                description: "Pretty print",
899                optional: true,
900            },
901        ],
902        returns: "string",
903        generic_return: None,
904    },
905    LuaFunction {
906        name: "from_yaml",
907        module: Some("data"),
908        description: "Parse YAML string to Lua value",
909        params: &[LuaParam {
910            name: "str",
911            typ: "string",
912            description: "YAML string",
913            optional: false,
914        }],
915        returns: "any",
916        generic_return: None,
917    },
918    LuaFunction {
919        name: "to_yaml",
920        module: Some("data"),
921        description: "Serialize Lua value to YAML string",
922        params: &[LuaParam {
923            name: "value",
924            typ: "any",
925            description: "Value to serialize",
926            optional: false,
927        }],
928        returns: "string",
929        generic_return: None,
930    },
931    LuaFunction {
932        name: "from_toml",
933        module: Some("data"),
934        description: "Parse TOML string to Lua value",
935        params: &[LuaParam {
936            name: "str",
937            typ: "string",
938            description: "TOML string",
939            optional: false,
940        }],
941        returns: "any",
942        generic_return: None,
943    },
944    LuaFunction {
945        name: "to_toml",
946        module: Some("data"),
947        description: "Serialize Lua value to TOML string",
948        params: &[LuaParam {
949            name: "value",
950            typ: "any",
951            description: "Value to serialize",
952            optional: false,
953        }],
954        returns: "string",
955        generic_return: None,
956    },
957    // rs.data.par - Parallel Data Loading
958    LuaFunction {
959        name: "load_json",
960        module: Some("data.par"),
961        description: "Load multiple JSON files in parallel",
962        params: &[LuaParam {
963            name: "paths",
964            typ: "string[]",
965            description: "Paths to JSON files",
966            optional: false,
967        }],
968        returns: "(table|nil)[]",
969        generic_return: None,
970    },
971    LuaFunction {
972        name: "load_yaml",
973        module: Some("data.par"),
974        description: "Load multiple YAML files in parallel",
975        params: &[LuaParam {
976            name: "paths",
977            typ: "string[]",
978            description: "Paths to YAML files",
979            optional: false,
980        }],
981        returns: "(table|nil)[]",
982        generic_return: None,
983    },
984    LuaFunction {
985        name: "load_frontmatter",
986        module: Some("data.par"),
987        description: "Parse frontmatter from multiple files in parallel",
988        params: &[LuaParam {
989            name: "paths",
990            typ: "string[]",
991            description: "Paths to markdown files",
992            optional: false,
993        }],
994        returns: "(FrontmatterResult|nil)[]",
995        generic_return: None,
996    },
997    // ========================================================================
998    // rs.image - Image Processing
999    // ========================================================================
1000    LuaFunction {
1001        name: "dimensions",
1002        module: Some("image"),
1003        description: "Get image width and height",
1004        params: &[LuaParam {
1005            name: "path",
1006            typ: "string",
1007            description: "Path to image",
1008            optional: false,
1009        }],
1010        returns: "ImageDimensions|nil",
1011        generic_return: None,
1012    },
1013    LuaFunction {
1014        name: "resize",
1015        module: Some("image"),
1016        description: "Resize image",
1017        params: &[
1018            LuaParam {
1019                name: "input",
1020                typ: "string",
1021                description: "Input path",
1022                optional: false,
1023            },
1024            LuaParam {
1025                name: "output",
1026                typ: "string",
1027                description: "Output path",
1028                optional: false,
1029            },
1030            LuaParam {
1031                name: "opts",
1032                typ: "{ width: number, height?: number, quality?: number }",
1033                description: "Resize options",
1034                optional: false,
1035            },
1036        ],
1037        returns: "boolean",
1038        generic_return: None,
1039    },
1040    LuaFunction {
1041        name: "convert",
1042        module: Some("image"),
1043        description: "Convert image format",
1044        params: &[
1045            LuaParam {
1046                name: "input",
1047                typ: "string",
1048                description: "Input path",
1049                optional: false,
1050            },
1051            LuaParam {
1052                name: "output",
1053                typ: "string",
1054                description: "Output path",
1055                optional: false,
1056            },
1057            LuaParam {
1058                name: "opts",
1059                typ: "{ format?: string, quality?: number }",
1060                description: "Convert options",
1061                optional: true,
1062            },
1063        ],
1064        returns: "boolean",
1065        generic_return: None,
1066    },
1067    LuaFunction {
1068        name: "optimize",
1069        module: Some("image"),
1070        description: "Optimize/compress image",
1071        params: &[
1072            LuaParam {
1073                name: "input",
1074                typ: "string",
1075                description: "Input path",
1076                optional: false,
1077            },
1078            LuaParam {
1079                name: "output",
1080                typ: "string",
1081                description: "Output path",
1082                optional: false,
1083            },
1084            LuaParam {
1085                name: "opts",
1086                typ: "{ quality?: number }",
1087                description: "Optimize options",
1088                optional: true,
1089            },
1090        ],
1091        returns: "boolean",
1092        generic_return: None,
1093    },
1094    // rs.image.par - Parallel Image Processing
1095    LuaFunction {
1096        name: "resize",
1097        module: Some("image.par"),
1098        description: "Resize multiple images in parallel",
1099        params: &[
1100            LuaParam {
1101                name: "inputs",
1102                typ: "string[]",
1103                description: "Input paths",
1104                optional: false,
1105            },
1106            LuaParam {
1107                name: "outputs",
1108                typ: "string[]",
1109                description: "Output paths",
1110                optional: false,
1111            },
1112            LuaParam {
1113                name: "opts",
1114                typ: "{ width: number, height?: number, quality?: number }",
1115                description: "Resize options",
1116                optional: false,
1117            },
1118        ],
1119        returns: "(boolean|string)[]",
1120        generic_return: None,
1121    },
1122    LuaFunction {
1123        name: "convert",
1124        module: Some("image.par"),
1125        description: "Convert multiple images in parallel",
1126        params: &[
1127            LuaParam {
1128                name: "inputs",
1129                typ: "string[]",
1130                description: "Input paths",
1131                optional: false,
1132            },
1133            LuaParam {
1134                name: "outputs",
1135                typ: "string[]",
1136                description: "Output paths",
1137                optional: false,
1138            },
1139            LuaParam {
1140                name: "opts",
1141                typ: "{ quality?: number }",
1142                description: "Convert options",
1143                optional: true,
1144            },
1145        ],
1146        returns: "(boolean|string)[]",
1147        generic_return: None,
1148    },
1149    LuaFunction {
1150        name: "optimize",
1151        module: Some("image.par"),
1152        description: "Optimize multiple images in parallel",
1153        params: &[
1154            LuaParam {
1155                name: "inputs",
1156                typ: "string[]",
1157                description: "Input paths",
1158                optional: false,
1159            },
1160            LuaParam {
1161                name: "outputs",
1162                typ: "string[]",
1163                description: "Output paths",
1164                optional: false,
1165            },
1166            LuaParam {
1167                name: "opts",
1168                typ: "{ quality?: number }",
1169                description: "Optimize options",
1170                optional: true,
1171            },
1172        ],
1173        returns: "(boolean|string)[]",
1174        generic_return: None,
1175    },
1176    // ========================================================================
1177    // rs.text - Text Operations
1178    // ========================================================================
1179    LuaFunction {
1180        name: "slugify",
1181        module: Some("text"),
1182        description: "Convert text to URL-friendly slug",
1183        params: &[LuaParam {
1184            name: "text",
1185            typ: "string",
1186            description: "Text to slugify",
1187            optional: false,
1188        }],
1189        returns: "string",
1190        generic_return: None,
1191    },
1192    LuaFunction {
1193        name: "word_count",
1194        module: Some("text"),
1195        description: "Count words in text",
1196        params: &[LuaParam {
1197            name: "text",
1198            typ: "string",
1199            description: "Text to count",
1200            optional: false,
1201        }],
1202        returns: "number",
1203        generic_return: None,
1204    },
1205    LuaFunction {
1206        name: "reading_time",
1207        module: Some("text"),
1208        description: "Calculate reading time in minutes",
1209        params: &[
1210            LuaParam {
1211                name: "text",
1212                typ: "string",
1213                description: "Text to analyze",
1214                optional: false,
1215            },
1216            LuaParam {
1217                name: "wpm",
1218                typ: "number",
1219                description: "Words per minute (default: 200)",
1220                optional: true,
1221            },
1222        ],
1223        returns: "number",
1224        generic_return: None,
1225    },
1226    LuaFunction {
1227        name: "truncate",
1228        module: Some("text"),
1229        description: "Truncate text with optional suffix",
1230        params: &[
1231            LuaParam {
1232                name: "text",
1233                typ: "string",
1234                description: "Text to truncate",
1235                optional: false,
1236            },
1237            LuaParam {
1238                name: "len",
1239                typ: "number",
1240                description: "Maximum length",
1241                optional: false,
1242            },
1243            LuaParam {
1244                name: "suffix",
1245                typ: "string",
1246                description: "Suffix (default: '...')",
1247                optional: true,
1248            },
1249        ],
1250        returns: "string",
1251        generic_return: None,
1252    },
1253    LuaFunction {
1254        name: "url_encode",
1255        module: Some("text"),
1256        description: "URL encode a string",
1257        params: &[LuaParam {
1258            name: "text",
1259            typ: "string",
1260            description: "Text to encode",
1261            optional: false,
1262        }],
1263        returns: "string",
1264        generic_return: None,
1265    },
1266    LuaFunction {
1267        name: "url_decode",
1268        module: Some("text"),
1269        description: "URL decode a string",
1270        params: &[LuaParam {
1271            name: "text",
1272            typ: "string",
1273            description: "Text to decode",
1274            optional: false,
1275        }],
1276        returns: "string",
1277        generic_return: None,
1278    },
1279    // ========================================================================
1280    // rs.date - Date Operations
1281    // ========================================================================
1282    LuaFunction {
1283        name: "now",
1284        module: Some("date"),
1285        description: "Get current Unix timestamp",
1286        params: &[],
1287        returns: "number",
1288        generic_return: None,
1289    },
1290    LuaFunction {
1291        name: "from_timestamp",
1292        module: Some("date"),
1293        description: "Convert Unix timestamp to datetime table",
1294        params: &[LuaParam {
1295            name: "ts",
1296            typ: "number",
1297            description: "Unix timestamp (seconds)",
1298            optional: false,
1299        }],
1300        returns: "DateTime|nil",
1301        generic_return: None,
1302    },
1303    LuaFunction {
1304        name: "to_timestamp",
1305        module: Some("date"),
1306        description: "Convert date/datetime to Unix timestamp",
1307        params: &[LuaParam {
1308            name: "date",
1309            typ: "number|string|DateTime",
1310            description: "Date to convert",
1311            optional: false,
1312        }],
1313        returns: "number|nil",
1314        generic_return: None,
1315    },
1316    LuaFunction {
1317        name: "format",
1318        module: Some("date"),
1319        description: "Format a date/datetime using strftime format",
1320        params: &[
1321            LuaParam {
1322                name: "date",
1323                typ: "number|string|DateTime",
1324                description: "Date to format (timestamp, string, or table)",
1325                optional: false,
1326            },
1327            LuaParam {
1328                name: "format",
1329                typ: "string",
1330                description: "Format string (strftime)",
1331                optional: false,
1332            },
1333        ],
1334        returns: "string|nil",
1335        generic_return: None,
1336    },
1337    LuaFunction {
1338        name: "parse",
1339        module: Some("date"),
1340        description: "Parse date/datetime string to table",
1341        params: &[
1342            LuaParam {
1343                name: "str",
1344                typ: "string",
1345                description: "Date string to parse",
1346                optional: false,
1347            },
1348            LuaParam {
1349                name: "format",
1350                typ: "string",
1351                description: "Custom strftime format (auto-detects if omitted)",
1352                optional: true,
1353            },
1354        ],
1355        returns: "DateTime|nil",
1356        generic_return: None,
1357    },
1358    LuaFunction {
1359        name: "rss_format",
1360        module: Some("date"),
1361        description: "Format date for RSS feeds (RFC 2822)",
1362        params: &[LuaParam {
1363            name: "date",
1364            typ: "number|string|DateTime",
1365            description: "Date to format",
1366            optional: false,
1367        }],
1368        returns: "string|nil",
1369        generic_return: None,
1370    },
1371    LuaFunction {
1372        name: "iso_format",
1373        module: Some("date"),
1374        description: "Format date as ISO 8601",
1375        params: &[LuaParam {
1376            name: "date",
1377            typ: "number|string|DateTime",
1378            description: "Date to format",
1379            optional: false,
1380        }],
1381        returns: "string|nil",
1382        generic_return: None,
1383    },
1384    LuaFunction {
1385        name: "add",
1386        module: Some("date"),
1387        description: "Add time to a date",
1388        params: &[
1389            LuaParam {
1390                name: "date",
1391                typ: "number|string|DateTime",
1392                description: "Base date",
1393                optional: false,
1394            },
1395            LuaParam {
1396                name: "delta",
1397                typ: "{ years?: number, months?: number, days?: number, hours?: number, mins?: number, secs?: number }",
1398                description: "Time to add",
1399                optional: false,
1400            },
1401        ],
1402        returns: "DateTime|nil",
1403        generic_return: None,
1404    },
1405    LuaFunction {
1406        name: "diff",
1407        module: Some("date"),
1408        description: "Get difference between two dates in seconds",
1409        params: &[
1410            LuaParam {
1411                name: "date1",
1412                typ: "number|string|DateTime",
1413                description: "First date",
1414                optional: false,
1415            },
1416            LuaParam {
1417                name: "date2",
1418                typ: "number|string|DateTime",
1419                description: "Second date",
1420                optional: false,
1421            },
1422        ],
1423        returns: "number|nil",
1424        generic_return: None,
1425    },
1426    // ========================================================================
1427    // rs.path - Path Operations
1428    // ========================================================================
1429    LuaFunction {
1430        name: "join",
1431        module: Some("path"),
1432        description: "Join path segments",
1433        params: &[LuaParam {
1434            name: "...",
1435            typ: "string",
1436            description: "Path segments",
1437            optional: false,
1438        }],
1439        returns: "string",
1440        generic_return: None,
1441    },
1442    LuaFunction {
1443        name: "basename",
1444        module: Some("path"),
1445        description: "Get file name from path",
1446        params: &[LuaParam {
1447            name: "path",
1448            typ: "string",
1449            description: "Path",
1450            optional: false,
1451        }],
1452        returns: "string",
1453        generic_return: None,
1454    },
1455    LuaFunction {
1456        name: "dirname",
1457        module: Some("path"),
1458        description: "Get directory from path",
1459        params: &[LuaParam {
1460            name: "path",
1461            typ: "string",
1462            description: "Path",
1463            optional: false,
1464        }],
1465        returns: "string",
1466        generic_return: None,
1467    },
1468    LuaFunction {
1469        name: "extension",
1470        module: Some("path"),
1471        description: "Get file extension",
1472        params: &[LuaParam {
1473            name: "path",
1474            typ: "string",
1475            description: "Path",
1476            optional: false,
1477        }],
1478        returns: "string",
1479        generic_return: None,
1480    },
1481    // ========================================================================
1482    // rs.hash - Hash Operations
1483    // ========================================================================
1484    LuaFunction {
1485        name: "content",
1486        module: Some("hash"),
1487        description: "Hash string content (xxHash64)",
1488        params: &[LuaParam {
1489            name: "content",
1490            typ: "string",
1491            description: "Content to hash",
1492            optional: false,
1493        }],
1494        returns: "string",
1495        generic_return: None,
1496    },
1497    LuaFunction {
1498        name: "file",
1499        module: Some("hash"),
1500        description: "Hash file contents",
1501        params: &[LuaParam {
1502            name: "path",
1503            typ: "string",
1504            description: "Path to file",
1505            optional: false,
1506        }],
1507        returns: "string|nil",
1508        generic_return: None,
1509    },
1510    // ========================================================================
1511    // rs.git - Git Operations
1512    // ========================================================================
1513    LuaFunction {
1514        name: "info",
1515        module: Some("git"),
1516        description: "Get git info for repo or file",
1517        params: &[LuaParam {
1518            name: "path",
1519            typ: "string",
1520            description: "Path to file/directory (optional, defaults to repo)",
1521            optional: true,
1522        }],
1523        returns: "GitInfo|nil",
1524        generic_return: None,
1525    },
1526    LuaFunction {
1527        name: "is_ignored",
1528        module: Some("git"),
1529        description: "Check if path is ignored by .gitignore",
1530        params: &[LuaParam {
1531            name: "path",
1532            typ: "string",
1533            description: "Path to check",
1534            optional: false,
1535        }],
1536        returns: "boolean",
1537        generic_return: None,
1538    },
1539    // ========================================================================
1540    // rs.html - HTML Operations
1541    // ========================================================================
1542    LuaFunction {
1543        name: "to_text",
1544        module: Some("html"),
1545        description: "Convert HTML to plain text",
1546        params: &[LuaParam {
1547            name: "html",
1548            typ: "string",
1549            description: "HTML content",
1550            optional: false,
1551        }],
1552        returns: "string",
1553        generic_return: None,
1554    },
1555    LuaFunction {
1556        name: "strip_tags",
1557        module: Some("html"),
1558        description: "Remove HTML tags",
1559        params: &[LuaParam {
1560            name: "html",
1561            typ: "string",
1562            description: "HTML content",
1563            optional: false,
1564        }],
1565        returns: "string",
1566        generic_return: None,
1567    },
1568    LuaFunction {
1569        name: "extract_links",
1570        module: Some("html"),
1571        description: "Extract links from HTML",
1572        params: &[LuaParam {
1573            name: "html",
1574            typ: "string",
1575            description: "HTML content",
1576            optional: false,
1577        }],
1578        returns: "string[]",
1579        generic_return: None,
1580    },
1581    LuaFunction {
1582        name: "extract_images",
1583        module: Some("html"),
1584        description: "Extract image paths from HTML",
1585        params: &[LuaParam {
1586            name: "html",
1587            typ: "string",
1588            description: "HTML content",
1589            optional: false,
1590        }],
1591        returns: "string[]",
1592        generic_return: None,
1593    },
1594    // ========================================================================
1595    // rs.log - Logging
1596    // ========================================================================
1597    LuaFunction {
1598        name: "trace",
1599        module: Some("log"),
1600        description: "Log at trace level",
1601        params: &[LuaParam {
1602            name: "...",
1603            typ: "string",
1604            description: "Messages to log",
1605            optional: false,
1606        }],
1607        returns: "nil",
1608        generic_return: None,
1609    },
1610    LuaFunction {
1611        name: "debug",
1612        module: Some("log"),
1613        description: "Log at debug level",
1614        params: &[LuaParam {
1615            name: "...",
1616            typ: "string",
1617            description: "Messages to log",
1618            optional: false,
1619        }],
1620        returns: "nil",
1621        generic_return: None,
1622    },
1623    LuaFunction {
1624        name: "info",
1625        module: Some("log"),
1626        description: "Log at info level",
1627        params: &[LuaParam {
1628            name: "...",
1629            typ: "string",
1630            description: "Messages to log",
1631            optional: false,
1632        }],
1633        returns: "nil",
1634        generic_return: None,
1635    },
1636    LuaFunction {
1637        name: "warn",
1638        module: Some("log"),
1639        description: "Log at warn level",
1640        params: &[LuaParam {
1641            name: "...",
1642            typ: "string",
1643            description: "Messages to log",
1644            optional: false,
1645        }],
1646        returns: "nil",
1647        generic_return: None,
1648    },
1649    LuaFunction {
1650        name: "error",
1651        module: Some("log"),
1652        description: "Log at error level",
1653        params: &[LuaParam {
1654            name: "...",
1655            typ: "string",
1656            description: "Messages to log",
1657            optional: false,
1658        }],
1659        returns: "nil",
1660        generic_return: None,
1661    },
1662    LuaFunction {
1663        name: "print",
1664        module: Some("log"),
1665        description: "Log message (always visible)",
1666        params: &[LuaParam {
1667            name: "...",
1668            typ: "string",
1669            description: "Messages to log",
1670            optional: false,
1671        }],
1672        returns: "nil",
1673        generic_return: None,
1674    },
1675    // ========================================================================
1676    // rs.env - Environment
1677    // ========================================================================
1678    LuaFunction {
1679        name: "get",
1680        module: Some("env"),
1681        description: "Get environment variable with optional default value",
1682        params: &[
1683            LuaParam {
1684                name: "name",
1685                typ: "string",
1686                description: "Variable name",
1687                optional: false,
1688            },
1689            LuaParam {
1690                name: "default",
1691                typ: "string",
1692                description: "Default value if variable is not set",
1693                optional: true,
1694            },
1695        ],
1696        returns: "string|nil",
1697        generic_return: None,
1698    },
1699    // ========================================================================
1700    // rs.markdown - Markdown Processing
1701    // ========================================================================
1702    // plugins sub-module (callable table)
1703    LuaFunction {
1704        name: "default",
1705        module: Some("markdown.plugins"),
1706        description: "Get default markdown plugins",
1707        params: &[LuaParam {
1708            name: "opts",
1709            typ: "{ lazy_images?: boolean, heading_anchors?: boolean, external_links?: boolean }",
1710            description: "Options to disable specific plugins",
1711            optional: true,
1712        }],
1713        returns: "function[]",
1714        generic_return: None,
1715    },
1716    LuaFunction {
1717        name: "lazy_images",
1718        module: Some("markdown.plugins"),
1719        description: "Plugin for lazy-loading images",
1720        params: &[LuaParam {
1721            name: "opts",
1722            typ: "table",
1723            description: "Plugin options",
1724            optional: true,
1725        }],
1726        returns: "function",
1727        generic_return: None,
1728    },
1729    LuaFunction {
1730        name: "heading_anchors",
1731        module: Some("markdown.plugins"),
1732        description: "Plugin for adding heading anchor IDs",
1733        params: &[LuaParam {
1734            name: "opts",
1735            typ: "table",
1736            description: "Plugin options",
1737            optional: true,
1738        }],
1739        returns: "function",
1740        generic_return: None,
1741    },
1742    LuaFunction {
1743        name: "external_links",
1744        module: Some("markdown.plugins"),
1745        description: "Plugin for external link attributes",
1746        params: &[LuaParam {
1747            name: "opts",
1748            typ: "table",
1749            description: "Plugin options",
1750            optional: true,
1751        }],
1752        returns: "function",
1753        generic_return: None,
1754    },
1755    LuaFunction {
1756        name: "render",
1757        module: Some("markdown"),
1758        description: "Render markdown to HTML",
1759        params: &[
1760            LuaParam {
1761                name: "content",
1762                typ: "string",
1763                description: "Markdown content",
1764                optional: false,
1765            },
1766            LuaParam {
1767                name: "opts",
1768                typ: "{ plugins?: function[] }",
1769                description: "Render options",
1770                optional: true,
1771            },
1772        ],
1773        returns: "string",
1774        generic_return: None,
1775    },
1776    LuaFunction {
1777        name: "extract_links",
1778        module: Some("markdown"),
1779        description: "Extract links from markdown",
1780        params: &[LuaParam {
1781            name: "content",
1782            typ: "string",
1783            description: "Markdown content",
1784            optional: false,
1785        }],
1786        returns: "string[]",
1787        generic_return: None,
1788    },
1789    LuaFunction {
1790        name: "extract_images",
1791        module: Some("markdown"),
1792        description: "Extract image paths from markdown",
1793        params: &[LuaParam {
1794            name: "content",
1795            typ: "string",
1796            description: "Markdown content",
1797            optional: false,
1798        }],
1799        returns: "string[]",
1800        generic_return: None,
1801    },
1802    // ========================================================================
1803    // rs.assets - Asset Hashing
1804    // ========================================================================
1805    LuaFunction {
1806        name: "hash",
1807        module: Some("assets"),
1808        description: "Compute hash of content, returns task for await",
1809        params: &[
1810            LuaParam {
1811                name: "content",
1812                typ: "string",
1813                description: "Content to hash",
1814                optional: false,
1815            },
1816            LuaParam {
1817                name: "length",
1818                typ: "number",
1819                description: "Hash length (default: 8)",
1820                optional: true,
1821            },
1822        ],
1823        returns: "AsyncIOTask",
1824        generic_return: Some("string"),
1825    },
1826    LuaFunction {
1827        name: "hash_sync",
1828        module: Some("assets"),
1829        description: "Compute hash of content synchronously",
1830        params: &[
1831            LuaParam {
1832                name: "content",
1833                typ: "string",
1834                description: "Content to hash",
1835                optional: false,
1836            },
1837            LuaParam {
1838                name: "length",
1839                typ: "number",
1840                description: "Hash length (default: 8)",
1841                optional: true,
1842            },
1843        ],
1844        returns: "string",
1845        generic_return: None,
1846    },
1847    LuaFunction {
1848        name: "write_hashed",
1849        module: Some("assets"),
1850        description: "Write content with hashed filename (async)",
1851        params: &[
1852            LuaParam {
1853                name: "content",
1854                typ: "string",
1855                description: "Content to write",
1856                optional: false,
1857            },
1858            LuaParam {
1859                name: "path",
1860                typ: "string",
1861                description: "Output path",
1862                optional: false,
1863            },
1864            LuaParam {
1865                name: "opts",
1866                typ: "{ hash_length?: number }",
1867                description: "Options",
1868                optional: true,
1869            },
1870        ],
1871        returns: "AsyncIOTask",
1872        generic_return: Some("string"),
1873    },
1874    LuaFunction {
1875        name: "get_path",
1876        module: Some("assets"),
1877        description: "Get hashed path for original",
1878        params: &[LuaParam {
1879            name: "path",
1880            typ: "string",
1881            description: "Original path",
1882            optional: false,
1883        }],
1884        returns: "string",
1885        generic_return: None,
1886    },
1887    LuaFunction {
1888        name: "register",
1889        module: Some("assets"),
1890        description: "Register a path mapping",
1891        params: &[
1892            LuaParam {
1893                name: "original",
1894                typ: "string",
1895                description: "Original path",
1896                optional: false,
1897            },
1898            LuaParam {
1899                name: "hashed",
1900                typ: "string",
1901                description: "Hashed path",
1902                optional: false,
1903            },
1904        ],
1905        returns: "nil",
1906        generic_return: None,
1907    },
1908    LuaFunction {
1909        name: "manifest",
1910        module: Some("assets"),
1911        description: "Get all asset mappings",
1912        params: &[],
1913        returns: "table<string, string>",
1914        generic_return: None,
1915    },
1916    LuaFunction {
1917        name: "clear",
1918        module: Some("assets"),
1919        description: "Clear the asset manifest",
1920        params: &[],
1921        returns: "nil",
1922        generic_return: None,
1923    },
1924    LuaFunction {
1925        name: "check_unused",
1926        module: Some("assets"),
1927        description: "Find assets not referenced in HTML/CSS",
1928        params: &[LuaParam {
1929            name: "output_dir",
1930            typ: "string",
1931            description: "Output directory to scan",
1932            optional: false,
1933        }],
1934        returns: "string[]",
1935        generic_return: None,
1936    },
1937    // ========================================================================
1938    // rs.js - JavaScript Processing
1939    // ========================================================================
1940    LuaFunction {
1941        name: "concat",
1942        module: Some("js"),
1943        description: "Concatenate JavaScript files (async)",
1944        params: &[
1945            LuaParam {
1946                name: "input",
1947                typ: "string|string[]",
1948                description: "Input path(s) or glob pattern",
1949                optional: false,
1950            },
1951            LuaParam {
1952                name: "output",
1953                typ: "string",
1954                description: "Output path",
1955                optional: false,
1956            },
1957            LuaParam {
1958                name: "opts",
1959                typ: "{ minify?: boolean }",
1960                description: "Options",
1961                optional: true,
1962            },
1963        ],
1964        returns: "AsyncIOTask",
1965        generic_return: Some("nil"),
1966    },
1967    LuaFunction {
1968        name: "bundle",
1969        module: Some("js"),
1970        description: "Bundle and minify JavaScript (async)",
1971        params: &[
1972            LuaParam {
1973                name: "input",
1974                typ: "string|string[]",
1975                description: "Input path(s)",
1976                optional: false,
1977            },
1978            LuaParam {
1979                name: "output",
1980                typ: "string",
1981                description: "Output path",
1982                optional: false,
1983            },
1984            LuaParam {
1985                name: "opts",
1986                typ: "{ minify?: boolean, treeshake?: boolean, format?: string }",
1987                description: "Options",
1988                optional: true,
1989            },
1990        ],
1991        returns: "AsyncIOTask",
1992        generic_return: Some("nil"),
1993    },
1994    // ========================================================================
1995    // rs.css - CSS Processing
1996    // ========================================================================
1997    LuaFunction {
1998        name: "concat",
1999        module: Some("css"),
2000        description: "Concatenate CSS files (async)",
2001        params: &[
2002            LuaParam {
2003                name: "input",
2004                typ: "string|string[]",
2005                description: "Input path(s) or glob pattern",
2006                optional: false,
2007            },
2008            LuaParam {
2009                name: "output",
2010                typ: "string",
2011                description: "Output path",
2012                optional: false,
2013            },
2014            LuaParam {
2015                name: "opts",
2016                typ: "{ minify?: boolean, purge?: boolean, safelist?: string[] }",
2017                description: "Options",
2018                optional: true,
2019            },
2020        ],
2021        returns: "AsyncIOTask",
2022        generic_return: Some("nil"),
2023    },
2024    LuaFunction {
2025        name: "bundle",
2026        module: Some("css"),
2027        description: "Bundle and minify CSS with LightningCSS (async)",
2028        params: &[
2029            LuaParam {
2030                name: "input",
2031                typ: "string|string[]",
2032                description: "Input path(s)",
2033                optional: false,
2034            },
2035            LuaParam {
2036                name: "output",
2037                typ: "string",
2038                description: "Output path",
2039                optional: false,
2040            },
2041            LuaParam {
2042                name: "opts",
2043                typ: "{ minify?: boolean, purge?: boolean, safelist?: string[] }",
2044                description: "Options",
2045                optional: true,
2046            },
2047        ],
2048        returns: "AsyncIOTask",
2049        generic_return: Some("nil"),
2050    },
2051    LuaFunction {
2052        name: "purge",
2053        module: Some("css"),
2054        description: "Purge unused CSS rules from a CSS file (async)",
2055        params: &[
2056            LuaParam {
2057                name: "css_path",
2058                typ: "string",
2059                description: "Path to CSS file",
2060                optional: false,
2061            },
2062            LuaParam {
2063                name: "options",
2064                typ: "{ safelist?: string[] }",
2065                description: "Purge options",
2066                optional: true,
2067            },
2068        ],
2069        returns: "AsyncIOTask",
2070        generic_return: Some("nil"),
2071    },
2072    LuaFunction {
2073        name: "critical",
2074        module: Some("css"),
2075        description: "Extract critical CSS for HTML content (async)",
2076        params: &[
2077            LuaParam {
2078                name: "html_content",
2079                typ: "string",
2080                description: "HTML content to analyze",
2081                optional: false,
2082            },
2083            LuaParam {
2084                name: "css_path",
2085                typ: "string",
2086                description: "Path to CSS file",
2087                optional: false,
2088            },
2089            LuaParam {
2090                name: "options",
2091                typ: "{ minify?: boolean, safelist?: string[] }",
2092                description: "Options",
2093                optional: true,
2094            },
2095        ],
2096        returns: "AsyncIOTask",
2097        generic_return: Some("string"),
2098    },
2099    LuaFunction {
2100        name: "inline_critical",
2101        module: Some("css"),
2102        description: "Inline critical CSS into HTML file (async)",
2103        params: &[
2104            LuaParam {
2105                name: "html_path",
2106                typ: "string",
2107                description: "Path to HTML file",
2108                optional: false,
2109            },
2110            LuaParam {
2111                name: "css_path",
2112                typ: "string",
2113                description: "Path to CSS file",
2114                optional: false,
2115            },
2116            LuaParam {
2117                name: "options",
2118                typ: "{ minify?: boolean, safelist?: string[], css_href?: string }",
2119                description: "Options",
2120                optional: true,
2121            },
2122        ],
2123        returns: "AsyncIOTask",
2124        generic_return: Some("nil"),
2125    },
2126    // ========================================================================
2127    // rs.fonts - Font Handling
2128    // ========================================================================
2129    LuaFunction {
2130        name: "download_google_font",
2131        module: Some("fonts"),
2132        description: "Download Google Font files (async)",
2133        params: &[
2134            LuaParam {
2135                name: "family",
2136                typ: "string",
2137                description: "Font family name",
2138                optional: false,
2139            },
2140            LuaParam {
2141                name: "options",
2142                typ: "{ fonts_dir: string, css_path: string, css_prefix?: string, weights?: number[], display?: string, cache?: boolean|string, minify?: boolean }",
2143                description: "Download options",
2144                optional: false,
2145            },
2146        ],
2147        returns: "AsyncIOTask",
2148        generic_return: Some("nil"),
2149    },
2150    // ========================================================================
2151    // rs.crypt - Encryption
2152    // ========================================================================
2153    LuaFunction {
2154        name: "encrypt",
2155        module: Some("crypt"),
2156        description: "Encrypt content with password",
2157        params: &[
2158            LuaParam {
2159                name: "content",
2160                typ: "string",
2161                description: "Content to encrypt",
2162                optional: false,
2163            },
2164            LuaParam {
2165                name: "password",
2166                typ: "string",
2167                description: "Encryption password",
2168                optional: true,
2169            },
2170        ],
2171        returns: "string",
2172        generic_return: None,
2173    },
2174    LuaFunction {
2175        name: "decrypt",
2176        module: Some("crypt"),
2177        description: "Decrypt content with password",
2178        params: &[
2179            LuaParam {
2180                name: "encrypted",
2181                typ: "string",
2182                description: "Encrypted content",
2183                optional: false,
2184            },
2185            LuaParam {
2186                name: "password",
2187                typ: "string",
2188                description: "Decryption password",
2189                optional: true,
2190            },
2191        ],
2192        returns: "string|nil",
2193        generic_return: None,
2194    },
2195    LuaFunction {
2196        name: "encrypt_html",
2197        module: Some("crypt"),
2198        description: "Encrypt HTML with embedded decryption",
2199        params: &[
2200            LuaParam {
2201                name: "html",
2202                typ: "string",
2203                description: "HTML to encrypt",
2204                optional: false,
2205            },
2206            LuaParam {
2207                name: "password",
2208                typ: "string",
2209                description: "Encryption password",
2210                optional: true,
2211            },
2212        ],
2213        returns: "string",
2214        generic_return: None,
2215    },
2216    // ========================================================================
2217    // rs.pwa - PWA Generation
2218    // ========================================================================
2219    LuaFunction {
2220        name: "manifest",
2221        module: Some("pwa"),
2222        description: "Generate PWA manifest.json (async)",
2223        params: &[LuaParam {
2224            name: "options",
2225            typ: "{ name: string, short_name: string, output: string, description?: string, start_url?: string, display?: string, background_color?: string, theme_color?: string, icons?: { src: string, sizes: string, type?: string, purpose?: string }[] }",
2226            description: "Manifest configuration",
2227            optional: false,
2228        }],
2229        returns: "AsyncIOTask",
2230        generic_return: Some("nil"),
2231    },
2232    LuaFunction {
2233        name: "service_worker",
2234        module: Some("pwa"),
2235        description: "Generate service worker (async)",
2236        params: &[LuaParam {
2237            name: "options",
2238            typ: "{ cache_name: string, output: string, version?: string, precache?: string[], network_first?: string[], cache_first?: string[], offline_page?: string }",
2239            description: "Service worker configuration",
2240            optional: false,
2241        }],
2242        returns: "AsyncIOTask",
2243        generic_return: Some("nil"),
2244    },
2245    // ========================================================================
2246    // rs.seo - SEO Generation
2247    // ========================================================================
2248    LuaFunction {
2249        name: "sitemap",
2250        module: Some("seo"),
2251        description: "Generate sitemap.xml (async)",
2252        params: &[LuaParam {
2253            name: "options",
2254            typ: "{ base_url: string, pages: (string | { path: string, lastmod?: string, changefreq?: string, priority?: number })[], output: string, default_changefreq?: string, default_priority?: number, exclude?: string[] }",
2255            description: "Sitemap configuration",
2256            optional: false,
2257        }],
2258        returns: "AsyncIOTask",
2259        generic_return: Some("nil"),
2260    },
2261    LuaFunction {
2262        name: "robots",
2263        module: Some("seo"),
2264        description: "Generate robots.txt (async)",
2265        params: &[LuaParam {
2266            name: "options",
2267            typ: "{ output: string, sitemap_url?: string, allow?: string[], disallow?: string[], user_agent?: string }",
2268            description: "Robots configuration",
2269            optional: false,
2270        }],
2271        returns: "AsyncIOTask",
2272        generic_return: Some("nil"),
2273    },
2274    // ========================================================================
2275    // rs.coro - Coroutines
2276    // ========================================================================
2277    LuaFunction {
2278        name: "task",
2279        module: Some("coro"),
2280        description: "Create a task from a function",
2281        params: &[LuaParam {
2282            name: "fn",
2283            typ: "function",
2284            description: "Function to run",
2285            optional: false,
2286        }],
2287        returns: "Task",
2288        generic_return: None,
2289    },
2290    LuaFunction {
2291        name: "await",
2292        module: Some("coro"),
2293        description: "Await a task result",
2294        params: &[LuaParam {
2295            name: "task",
2296            typ: "Task",
2297            description: "Task to await",
2298            optional: false,
2299        }],
2300        returns: "any",
2301        generic_return: None,
2302    },
2303    // ========================================================================
2304    // rs.parallel - Parallel Processing (legacy)
2305    // ========================================================================
2306    LuaFunction {
2307        name: "map",
2308        module: Some("parallel"),
2309        description: "Parallel map with optional context",
2310        params: &[
2311            LuaParam {
2312                name: "items",
2313                typ: "T[]",
2314                description: "Items to process",
2315                optional: false,
2316            },
2317            LuaParam {
2318                name: "fn",
2319                typ: "fun(item: T, ctx: table?): U",
2320                description: "Transform function",
2321                optional: false,
2322            },
2323            LuaParam {
2324                name: "ctx",
2325                typ: "table",
2326                description: "Context passed to each call",
2327                optional: true,
2328            },
2329        ],
2330        returns: "U[]",
2331        generic_return: None,
2332    },
2333    LuaFunction {
2334        name: "filter",
2335        module: Some("parallel"),
2336        description: "Parallel filter with optional context",
2337        params: &[
2338            LuaParam {
2339                name: "items",
2340                typ: "T[]",
2341                description: "Items to filter",
2342                optional: false,
2343            },
2344            LuaParam {
2345                name: "fn",
2346                typ: "fun(item: T, ctx: table?): boolean",
2347                description: "Predicate function",
2348                optional: false,
2349            },
2350            LuaParam {
2351                name: "ctx",
2352                typ: "table",
2353                description: "Context passed to each call",
2354                optional: true,
2355            },
2356        ],
2357        returns: "T[]",
2358        generic_return: None,
2359    },
2360    // ========================================================================
2361    // rs.async - Async I/O
2362    // ========================================================================
2363    LuaFunction {
2364        name: "fetch",
2365        module: Some("async"),
2366        description: "Fetch URL content (async)",
2367        params: &[
2368            LuaParam {
2369                name: "url",
2370                typ: "string",
2371                description: "URL to fetch",
2372                optional: false,
2373            },
2374            LuaParam {
2375                name: "opts",
2376                typ: "{ method?: string, headers?: table, body?: string, timeout?: number, cache?: boolean|string }",
2377                description: "Request options",
2378                optional: true,
2379            },
2380        ],
2381        returns: "AsyncTask",
2382        generic_return: Some("FetchResponse"),
2383    },
2384    LuaFunction {
2385        name: "fetch_sync",
2386        module: Some("async"),
2387        description: "Fetch URL content synchronously",
2388        params: &[
2389            LuaParam {
2390                name: "url",
2391                typ: "string",
2392                description: "URL to fetch",
2393                optional: false,
2394            },
2395            LuaParam {
2396                name: "opts",
2397                typ: "{ method?: string, headers?: table, body?: string, timeout?: number, cache?: boolean|string }",
2398                description: "Request options",
2399                optional: true,
2400            },
2401        ],
2402        returns: "FetchResponse",
2403        generic_return: None,
2404    },
2405    LuaFunction {
2406        name: "fetch_json",
2407        module: Some("async"),
2408        description: "Fetch and parse JSON",
2409        params: &[
2410            LuaParam {
2411                name: "url",
2412                typ: "string",
2413                description: "URL to fetch",
2414                optional: false,
2415            },
2416            LuaParam {
2417                name: "opts",
2418                typ: "{ method?: string, headers?: table, body?: string, timeout?: number }",
2419                description: "Request options",
2420                optional: true,
2421            },
2422        ],
2423        returns: "any",
2424        generic_return: None,
2425    },
2426    LuaFunction {
2427        name: "fetch_bytes",
2428        module: Some("async"),
2429        description: "Fetch binary data, returns task for await",
2430        params: &[
2431            LuaParam {
2432                name: "url",
2433                typ: "string",
2434                description: "URL to fetch",
2435                optional: false,
2436            },
2437            LuaParam {
2438                name: "opts",
2439                typ: "{ method?: string, headers?: table, body?: string, timeout?: number, cache?: boolean|string }",
2440                description: "Request options",
2441                optional: true,
2442            },
2443        ],
2444        returns: "AsyncTask",
2445        generic_return: Some("FetchResponse"),
2446    },
2447    LuaFunction {
2448        name: "fetch_bytes_sync",
2449        module: Some("async"),
2450        description: "Fetch binary data synchronously",
2451        params: &[
2452            LuaParam {
2453                name: "url",
2454                typ: "string",
2455                description: "URL to fetch",
2456                optional: false,
2457            },
2458            LuaParam {
2459                name: "opts",
2460                typ: "{ method?: string, headers?: table, body?: string, timeout?: number, cache?: boolean|string }",
2461                description: "Request options",
2462                optional: true,
2463            },
2464        ],
2465        returns: "{ status: number, ok: boolean, body: string }",
2466        generic_return: None,
2467    },
2468    LuaFunction {
2469        name: "fetch_all",
2470        module: Some("async"),
2471        description: "Fetch multiple URLs concurrently",
2472        params: &[LuaParam {
2473            name: "requests",
2474            typ: "(string | { url: string, options?: table })[]",
2475            description: "URLs or request objects",
2476            optional: false,
2477        }],
2478        returns: "FetchResponse[]",
2479        generic_return: None,
2480    },
2481    LuaFunction {
2482        name: "spawn",
2483        module: Some("async"),
2484        description: "Spawn a fetch task for later await",
2485        params: &[
2486            LuaParam {
2487                name: "url",
2488                typ: "string",
2489                description: "URL to fetch",
2490                optional: false,
2491            },
2492            LuaParam {
2493                name: "opts",
2494                typ: "{ method?: string, headers?: table, body?: string }",
2495                description: "Request options",
2496                optional: true,
2497            },
2498        ],
2499        returns: "AsyncTask",
2500        generic_return: Some("FetchResponse"),
2501    },
2502    LuaFunction {
2503        name: "wrap",
2504        module: Some("async"),
2505        description: "Wrap a Lua function for deferred execution",
2506        params: &[LuaParam {
2507            name: "fn",
2508            typ: "function",
2509            description: "Function to wrap",
2510            optional: false,
2511        }],
2512        returns: "AsyncLuaTask",
2513        generic_return: Some("T"),
2514    },
2515    LuaFunction {
2516        name: "await",
2517        module: Some("async"),
2518        description: "Await an async task",
2519        params: &[LuaParam {
2520            name: "task",
2521            typ: "AsyncTask|AsyncIOTask|AsyncLuaTask",
2522            description: "Task to await",
2523            optional: false,
2524        }],
2525        returns: "any",
2526        generic_return: None,
2527    },
2528    LuaFunction {
2529        name: "await_all",
2530        module: Some("async"),
2531        description: "Await multiple tasks concurrently",
2532        params: &[LuaParam {
2533            name: "tasks",
2534            typ: "(AsyncTask|AsyncIOTask|AsyncLuaTask)[]",
2535            description: "Tasks to await",
2536            optional: false,
2537        }],
2538        returns: "any[]",
2539        generic_return: None,
2540    },
2541    LuaFunction {
2542        name: "read_file",
2543        module: Some("async"),
2544        description: "Read text file, returns task for await",
2545        params: &[LuaParam {
2546            name: "path",
2547            typ: "string",
2548            description: "Path to file",
2549            optional: false,
2550        }],
2551        returns: "AsyncIOTask",
2552        generic_return: Some("string"),
2553    },
2554    LuaFunction {
2555        name: "read_files",
2556        module: Some("async"),
2557        description: "Read multiple files concurrently, returns task for await",
2558        params: &[LuaParam {
2559            name: "paths",
2560            typ: "string[]",
2561            description: "Paths to read",
2562            optional: false,
2563        }],
2564        returns: "AsyncIOTask",
2565        generic_return: Some("(string|nil)[]"),
2566    },
2567    LuaFunction {
2568        name: "write_file",
2569        module: Some("async"),
2570        description: "Write text file, returns task for await",
2571        params: &[
2572            LuaParam {
2573                name: "path",
2574                typ: "string",
2575                description: "Path to write",
2576                optional: false,
2577            },
2578            LuaParam {
2579                name: "content",
2580                typ: "string",
2581                description: "Content to write",
2582                optional: false,
2583            },
2584        ],
2585        returns: "AsyncIOTask",
2586        generic_return: Some("boolean"),
2587    },
2588    LuaFunction {
2589        name: "write",
2590        module: Some("async"),
2591        description: "Write binary file, returns task for await",
2592        params: &[
2593            LuaParam {
2594                name: "path",
2595                typ: "string",
2596                description: "Path to write",
2597                optional: false,
2598            },
2599            LuaParam {
2600                name: "data",
2601                typ: "string",
2602                description: "Binary data to write",
2603                optional: false,
2604            },
2605        ],
2606        returns: "AsyncIOTask",
2607        generic_return: Some("boolean"),
2608    },
2609    LuaFunction {
2610        name: "exists",
2611        module: Some("async"),
2612        description: "Check if path exists, returns task for await",
2613        params: &[LuaParam {
2614            name: "path",
2615            typ: "string",
2616            description: "Path to check",
2617            optional: false,
2618        }],
2619        returns: "AsyncIOTask",
2620        generic_return: Some("boolean"),
2621    },
2622    LuaFunction {
2623        name: "load_json",
2624        module: Some("async"),
2625        description: "Load and parse JSON file, returns task for await",
2626        params: &[LuaParam {
2627            name: "path",
2628            typ: "string",
2629            description: "Path to JSON file",
2630            optional: false,
2631        }],
2632        returns: "AsyncIOTask",
2633        generic_return: Some("any"),
2634    },
2635    LuaFunction {
2636        name: "copy_file",
2637        module: Some("async"),
2638        description: "Copy file, returns task for await",
2639        params: &[
2640            LuaParam {
2641                name: "src",
2642                typ: "string",
2643                description: "Source path",
2644                optional: false,
2645            },
2646            LuaParam {
2647                name: "dst",
2648                typ: "string",
2649                description: "Destination path",
2650                optional: false,
2651            },
2652        ],
2653        returns: "AsyncIOTask",
2654        generic_return: Some("number"),
2655    },
2656    LuaFunction {
2657        name: "rename",
2658        module: Some("async"),
2659        description: "Rename file or directory, returns task for await",
2660        params: &[
2661            LuaParam {
2662                name: "src",
2663                typ: "string",
2664                description: "Source path",
2665                optional: false,
2666            },
2667            LuaParam {
2668                name: "dst",
2669                typ: "string",
2670                description: "Destination path",
2671                optional: false,
2672            },
2673        ],
2674        returns: "AsyncIOTask",
2675        generic_return: Some("boolean"),
2676    },
2677    LuaFunction {
2678        name: "create_dir",
2679        module: Some("async"),
2680        description: "Create directory, returns task for await",
2681        params: &[LuaParam {
2682            name: "path",
2683            typ: "string",
2684            description: "Directory path",
2685            optional: false,
2686        }],
2687        returns: "AsyncIOTask",
2688        generic_return: Some("boolean"),
2689    },
2690    LuaFunction {
2691        name: "remove_file",
2692        module: Some("async"),
2693        description: "Remove file, returns task for await",
2694        params: &[LuaParam {
2695            name: "path",
2696            typ: "string",
2697            description: "File path",
2698            optional: false,
2699        }],
2700        returns: "AsyncIOTask",
2701        generic_return: Some("boolean"),
2702    },
2703    LuaFunction {
2704        name: "remove_dir",
2705        module: Some("async"),
2706        description: "Remove directory recursively, returns task for await",
2707        params: &[LuaParam {
2708            name: "path",
2709            typ: "string",
2710            description: "Directory path",
2711            optional: false,
2712        }],
2713        returns: "AsyncIOTask",
2714        generic_return: Some("boolean"),
2715    },
2716    LuaFunction {
2717        name: "metadata",
2718        module: Some("async"),
2719        description: "Get file metadata, returns task for await",
2720        params: &[LuaParam {
2721            name: "path",
2722            typ: "string",
2723            description: "Path to file/directory",
2724            optional: false,
2725        }],
2726        returns: "AsyncIOTask",
2727        generic_return: Some("FileMetadata"),
2728    },
2729    LuaFunction {
2730        name: "read_dir",
2731        module: Some("async"),
2732        description: "List directory contents, returns task for await",
2733        params: &[LuaParam {
2734            name: "path",
2735            typ: "string",
2736            description: "Directory path",
2737            optional: false,
2738        }],
2739        returns: "AsyncIOTask",
2740        generic_return: Some("DirEntry[]"),
2741    },
2742    LuaFunction {
2743        name: "canonicalize",
2744        module: Some("async"),
2745        description: "Get canonical/absolute path, returns task for await",
2746        params: &[LuaParam {
2747            name: "path",
2748            typ: "string",
2749            description: "Path to resolve",
2750            optional: false,
2751        }],
2752        returns: "AsyncIOTask",
2753        generic_return: Some("string"),
2754    },
2755];
2756
2757// ============================================================================
2758// DOCUMENTATION GENERATORS
2759// ============================================================================
2760
2761/// Generate EmmyLua annotations
2762pub fn generate_emmylua() -> String {
2763    let mut output = String::new();
2764    output.push_str("---@meta rs-web\n\n");
2765    output.push_str("-- Auto-generated EmmyLua annotations for rs-web\n\n");
2766
2767    // Generate class definitions
2768    for class in LUA_CLASSES {
2769        if class.is_generic {
2770            // Generic class with type parameter
2771            output.push_str(&format!("---@class {}<T>\n", class.name));
2772        } else {
2773            output.push_str(&format!("---@class {}\n", class.name));
2774        }
2775        for field in class.fields {
2776            output.push_str(&format!(
2777                "---@field {} {} {}\n",
2778                field.name, field.typ, field.description
2779            ));
2780        }
2781        output.push('\n');
2782    }
2783
2784    // Generate module structure
2785    output.push_str("---@class rs\n");
2786    output.push_str("local rs = {}\n\n");
2787
2788    // Group functions by module
2789    let mut modules: std::collections::HashMap<&str, Vec<&LuaFunction>> =
2790        std::collections::HashMap::new();
2791    for func in LUA_FUNCTIONS {
2792        let mod_name = func.module.unwrap_or("");
2793        modules.entry(mod_name).or_default().push(func);
2794    }
2795
2796    // Track declared modules to avoid duplicates
2797    let mut declared_modules: std::collections::HashSet<String> = std::collections::HashSet::new();
2798
2799    // Generate each module
2800    for (mod_name, funcs) in &modules {
2801        if mod_name.is_empty() {
2802            continue;
2803        }
2804
2805        let parts: Vec<&str> = mod_name.split('.').collect();
2806
2807        // Declare all parent modules first
2808        let mut current_path = String::new();
2809        for (i, part) in parts.iter().enumerate() {
2810            if i > 0 {
2811                current_path.push('.');
2812            }
2813            current_path.push_str(part);
2814
2815            if !declared_modules.contains(&current_path) {
2816                declared_modules.insert(current_path.clone());
2817                output.push_str(&format!("---@class rs.{}\n", current_path));
2818                output.push_str(&format!("rs.{} = {{}}\n\n", current_path));
2819            }
2820        }
2821
2822        for func in funcs {
2823            // Generate function documentation
2824            output.push_str(&format!("--- {}\n", func.description));
2825            for param in func.params {
2826                let optional = if param.optional { "?" } else { "" };
2827                output.push_str(&format!(
2828                    "---@param {}{} {} {}\n",
2829                    param.name, optional, param.typ, param.description
2830                ));
2831            }
2832
2833            // Handle generic return types
2834            let return_type = if let Some(inner_type) = func.generic_return {
2835                format!("{}<{}>", func.returns, inner_type)
2836            } else {
2837                func.returns.to_string()
2838            };
2839            output.push_str(&format!("---@return {}\n", return_type));
2840
2841            output.push_str(&format!("function rs.{}.{}(", mod_name, func.name));
2842            let param_names: Vec<&str> = func.params.iter().map(|p| p.name).collect();
2843            output.push_str(&param_names.join(", "));
2844            output.push_str(") end\n\n");
2845        }
2846    }
2847
2848    output.push_str("return rs\n");
2849    output
2850}
2851
2852/// Generate markdown documentation
2853pub fn generate_markdown() -> String {
2854    let mut output = String::new();
2855    output.push_str("# Lua API Reference\n\n");
2856
2857    // Group functions by module
2858    let mut modules: std::collections::BTreeMap<&str, Vec<&LuaFunction>> =
2859        std::collections::BTreeMap::new();
2860    for func in LUA_FUNCTIONS {
2861        let mod_name = func.module.unwrap_or("rs");
2862        modules.entry(mod_name).or_default().push(func);
2863    }
2864
2865    for (mod_name, funcs) in modules {
2866        output.push_str(&format!("## rs.{}\n\n", mod_name));
2867
2868        for func in funcs {
2869            output.push_str(&format!("### `rs.{}.{}`\n\n", mod_name, func.name));
2870            output.push_str(&format!("{}\n\n", func.description));
2871
2872            if !func.params.is_empty() {
2873                output.push_str("**Parameters:**\n\n");
2874                for param in func.params {
2875                    let optional = if param.optional { " (optional)" } else { "" };
2876                    output.push_str(&format!(
2877                        "- `{}`: `{}`{} - {}\n",
2878                        param.name, param.typ, optional, param.description
2879                    ));
2880                }
2881                output.push('\n');
2882            }
2883
2884            output.push_str(&format!("**Returns:** `{}`\n\n", func.returns));
2885        }
2886    }
2887
2888    output
2889}