Skip to main content

shape_runtime/stdlib_io/
mod.rs

1//! Native `io` module for file system and network operations.
2//!
3//! Exports: io.open(), io.read(), io.write(), io.close(), io.exists(), io.stat(),
4//! io.mkdir(), io.remove(), io.rename(), io.read_dir(), io.join(), io.dirname(),
5//! io.basename(), io.extension(), io.resolve(),
6//! io.tcp_connect(), io.tcp_listen(), io.tcp_accept(), io.tcp_read(),
7//! io.tcp_write(), io.tcp_close(), io.udp_bind(), io.udp_send(), io.udp_recv()
8
9pub mod async_file_ops;
10pub mod file_ops;
11pub mod network_ops;
12pub mod path_ops;
13pub mod process_ops;
14
15use crate::module_exports::{ModuleExports, ModuleFunction, ModuleParam};
16
17/// Create the `io` module with file system operations.
18pub fn create_io_module() -> ModuleExports {
19    let mut module = ModuleExports::new("std::core::io");
20    module.description = "File system and path operations".to_string();
21
22    // === File handle operations ===
23
24    module.add_function_with_schema(
25        "open",
26        file_ops::io_open,
27        ModuleFunction {
28            description: "Open a file and return a handle".to_string(),
29            params: vec![
30                ModuleParam {
31                    name: "path".to_string(),
32                    type_name: "string".to_string(),
33                    required: true,
34                    description: "File path to open".to_string(),
35                    ..Default::default()
36                },
37                ModuleParam {
38                    name: "mode".to_string(),
39                    type_name: "string".to_string(),
40                    required: false,
41                    description: "Open mode: \"r\" (default), \"w\", \"a\", \"rw\"".to_string(),
42                    default_snippet: Some("\"r\"".to_string()),
43                    allowed_values: Some(vec![
44                        "r".to_string(),
45                        "w".to_string(),
46                        "a".to_string(),
47                        "rw".to_string(),
48                    ]),
49                    ..Default::default()
50                },
51            ],
52            return_type: Some("IoHandle".to_string()),
53        },
54    );
55
56    module.add_function_with_schema(
57        "read",
58        file_ops::io_read,
59        ModuleFunction {
60            description: "Read from a file handle (n bytes or all)".to_string(),
61            params: vec![
62                ModuleParam {
63                    name: "handle".to_string(),
64                    type_name: "IoHandle".to_string(),
65                    required: true,
66                    description: "File handle from io.open()".to_string(),
67                    ..Default::default()
68                },
69                ModuleParam {
70                    name: "n".to_string(),
71                    type_name: "int".to_string(),
72                    required: false,
73                    description: "Number of bytes to read (omit for all)".to_string(),
74                    ..Default::default()
75                },
76            ],
77            return_type: Some("string".to_string()),
78        },
79    );
80
81    module.add_function_with_schema(
82        "read_to_string",
83        file_ops::io_read_to_string,
84        ModuleFunction {
85            description: "Read entire file as a string".to_string(),
86            params: vec![ModuleParam {
87                name: "handle".to_string(),
88                type_name: "IoHandle".to_string(),
89                required: true,
90                description: "File handle from io.open()".to_string(),
91                ..Default::default()
92            }],
93            return_type: Some("string".to_string()),
94        },
95    );
96
97    module.add_function_with_schema(
98        "read_bytes",
99        file_ops::io_read_bytes,
100        ModuleFunction {
101            description: "Read bytes from a file as array of ints".to_string(),
102            params: vec![
103                ModuleParam {
104                    name: "handle".to_string(),
105                    type_name: "IoHandle".to_string(),
106                    required: true,
107                    description: "File handle from io.open()".to_string(),
108                    ..Default::default()
109                },
110                ModuleParam {
111                    name: "n".to_string(),
112                    type_name: "int".to_string(),
113                    required: false,
114                    description: "Number of bytes to read (omit for all)".to_string(),
115                    ..Default::default()
116                },
117            ],
118            return_type: Some("Vec<int>".to_string()),
119        },
120    );
121
122    module.add_function_with_schema(
123        "write",
124        file_ops::io_write,
125        ModuleFunction {
126            description: "Write string or bytes to a file".to_string(),
127            params: vec![
128                ModuleParam {
129                    name: "handle".to_string(),
130                    type_name: "IoHandle".to_string(),
131                    required: true,
132                    description: "File handle from io.open()".to_string(),
133                    ..Default::default()
134                },
135                ModuleParam {
136                    name: "data".to_string(),
137                    type_name: "string".to_string(),
138                    required: true,
139                    description: "Data to write".to_string(),
140                    ..Default::default()
141                },
142            ],
143            return_type: Some("int".to_string()),
144        },
145    );
146
147    module.add_function_with_schema(
148        "close",
149        file_ops::io_close,
150        ModuleFunction {
151            description: "Close a file handle".to_string(),
152            params: vec![ModuleParam {
153                name: "handle".to_string(),
154                type_name: "IoHandle".to_string(),
155                required: true,
156                description: "File handle to close".to_string(),
157                ..Default::default()
158            }],
159            return_type: Some("bool".to_string()),
160        },
161    );
162
163    module.add_function_with_schema(
164        "flush",
165        file_ops::io_flush,
166        ModuleFunction {
167            description: "Flush buffered writes to disk".to_string(),
168            params: vec![ModuleParam {
169                name: "handle".to_string(),
170                type_name: "IoHandle".to_string(),
171                required: true,
172                description: "File handle to flush".to_string(),
173                ..Default::default()
174            }],
175            return_type: Some("unit".to_string()),
176        },
177    );
178
179    // === Stat operations (no handle needed) ===
180
181    module.add_function_with_schema(
182        "exists",
183        file_ops::io_exists,
184        ModuleFunction {
185            description: "Check if a path exists".to_string(),
186            params: vec![ModuleParam {
187                name: "path".to_string(),
188                type_name: "string".to_string(),
189                required: true,
190                description: "Path to check".to_string(),
191                ..Default::default()
192            }],
193            return_type: Some("bool".to_string()),
194        },
195    );
196
197    module.add_function_with_schema(
198        "stat",
199        file_ops::io_stat,
200        ModuleFunction {
201            description: "Get file/directory metadata".to_string(),
202            params: vec![ModuleParam {
203                name: "path".to_string(),
204                type_name: "string".to_string(),
205                required: true,
206                description: "Path to stat".to_string(),
207                ..Default::default()
208            }],
209            return_type: Some("object".to_string()),
210        },
211    );
212
213    module.add_function_with_schema(
214        "is_file",
215        file_ops::io_is_file,
216        ModuleFunction {
217            description: "Check if path is a file".to_string(),
218            params: vec![ModuleParam {
219                name: "path".to_string(),
220                type_name: "string".to_string(),
221                required: true,
222                description: "Path to check".to_string(),
223                ..Default::default()
224            }],
225            return_type: Some("bool".to_string()),
226        },
227    );
228
229    module.add_function_with_schema(
230        "is_dir",
231        file_ops::io_is_dir,
232        ModuleFunction {
233            description: "Check if path is a directory".to_string(),
234            params: vec![ModuleParam {
235                name: "path".to_string(),
236                type_name: "string".to_string(),
237                required: true,
238                description: "Path to check".to_string(),
239                ..Default::default()
240            }],
241            return_type: Some("bool".to_string()),
242        },
243    );
244
245    // === Directory operations ===
246
247    module.add_function_with_schema(
248        "mkdir",
249        file_ops::io_mkdir,
250        ModuleFunction {
251            description: "Create a directory".to_string(),
252            params: vec![
253                ModuleParam {
254                    name: "path".to_string(),
255                    type_name: "string".to_string(),
256                    required: true,
257                    description: "Directory path to create".to_string(),
258                    ..Default::default()
259                },
260                ModuleParam {
261                    name: "recursive".to_string(),
262                    type_name: "bool".to_string(),
263                    required: false,
264                    description: "Create parent directories if needed".to_string(),
265                    default_snippet: Some("false".to_string()),
266                    ..Default::default()
267                },
268            ],
269            return_type: Some("unit".to_string()),
270        },
271    );
272
273    module.add_function_with_schema(
274        "remove",
275        file_ops::io_remove,
276        ModuleFunction {
277            description: "Remove a file or directory".to_string(),
278            params: vec![ModuleParam {
279                name: "path".to_string(),
280                type_name: "string".to_string(),
281                required: true,
282                description: "Path to remove".to_string(),
283                ..Default::default()
284            }],
285            return_type: Some("unit".to_string()),
286        },
287    );
288
289    module.add_function_with_schema(
290        "rename",
291        file_ops::io_rename,
292        ModuleFunction {
293            description: "Rename/move a file or directory".to_string(),
294            params: vec![
295                ModuleParam {
296                    name: "old".to_string(),
297                    type_name: "string".to_string(),
298                    required: true,
299                    description: "Current path".to_string(),
300                    ..Default::default()
301                },
302                ModuleParam {
303                    name: "new".to_string(),
304                    type_name: "string".to_string(),
305                    required: true,
306                    description: "New path".to_string(),
307                    ..Default::default()
308                },
309            ],
310            return_type: Some("unit".to_string()),
311        },
312    );
313
314    module.add_function_with_schema(
315        "read_dir",
316        file_ops::io_read_dir,
317        ModuleFunction {
318            description: "List directory contents".to_string(),
319            params: vec![ModuleParam {
320                name: "path".to_string(),
321                type_name: "string".to_string(),
322                required: true,
323                description: "Directory path to list".to_string(),
324                ..Default::default()
325            }],
326            return_type: Some("Vec<string>".to_string()),
327        },
328    );
329
330    // === Path operations (sync, pure string manipulation) ===
331
332    module.add_function_with_schema(
333        "join",
334        path_ops::io_join,
335        ModuleFunction {
336            description: "Join path components".to_string(),
337            params: vec![ModuleParam {
338                name: "parts".to_string(),
339                type_name: "string".to_string(),
340                required: true,
341                description: "Path components to join".to_string(),
342                ..Default::default()
343            }],
344            return_type: Some("string".to_string()),
345        },
346    );
347
348    module.add_function_with_schema(
349        "dirname",
350        path_ops::io_dirname,
351        ModuleFunction {
352            description: "Get parent directory of a path".to_string(),
353            params: vec![ModuleParam {
354                name: "path".to_string(),
355                type_name: "string".to_string(),
356                required: true,
357                description: "File path".to_string(),
358                ..Default::default()
359            }],
360            return_type: Some("string".to_string()),
361        },
362    );
363
364    module.add_function_with_schema(
365        "basename",
366        path_ops::io_basename,
367        ModuleFunction {
368            description: "Get filename component of a path".to_string(),
369            params: vec![ModuleParam {
370                name: "path".to_string(),
371                type_name: "string".to_string(),
372                required: true,
373                description: "File path".to_string(),
374                ..Default::default()
375            }],
376            return_type: Some("string".to_string()),
377        },
378    );
379
380    module.add_function_with_schema(
381        "extension",
382        path_ops::io_extension,
383        ModuleFunction {
384            description: "Get file extension".to_string(),
385            params: vec![ModuleParam {
386                name: "path".to_string(),
387                type_name: "string".to_string(),
388                required: true,
389                description: "File path".to_string(),
390                ..Default::default()
391            }],
392            return_type: Some("string".to_string()),
393        },
394    );
395
396    module.add_function_with_schema(
397        "resolve",
398        path_ops::io_resolve,
399        ModuleFunction {
400            description: "Resolve/canonicalize a path".to_string(),
401            params: vec![ModuleParam {
402                name: "path".to_string(),
403                type_name: "string".to_string(),
404                required: true,
405                description: "Path to resolve".to_string(),
406                ..Default::default()
407            }],
408            return_type: Some("string".to_string()),
409        },
410    );
411
412    // === TCP operations ===
413
414    module.add_function_with_schema(
415        "tcp_connect",
416        network_ops::io_tcp_connect,
417        ModuleFunction {
418            description: "Connect to a TCP server".to_string(),
419            params: vec![ModuleParam {
420                name: "addr".to_string(),
421                type_name: "string".to_string(),
422                required: true,
423                description: "Address to connect to (e.g. \"127.0.0.1:8080\")".to_string(),
424                ..Default::default()
425            }],
426            return_type: Some("IoHandle".to_string()),
427        },
428    );
429
430    module.add_function_with_schema(
431        "tcp_listen",
432        network_ops::io_tcp_listen,
433        ModuleFunction {
434            description: "Bind a TCP listener".to_string(),
435            params: vec![ModuleParam {
436                name: "addr".to_string(),
437                type_name: "string".to_string(),
438                required: true,
439                description: "Address to bind (e.g. \"0.0.0.0:8080\")".to_string(),
440                ..Default::default()
441            }],
442            return_type: Some("IoHandle".to_string()),
443        },
444    );
445
446    module.add_function_with_schema(
447        "tcp_accept",
448        network_ops::io_tcp_accept,
449        ModuleFunction {
450            description: "Accept an incoming TCP connection".to_string(),
451            params: vec![ModuleParam {
452                name: "listener".to_string(),
453                type_name: "IoHandle".to_string(),
454                required: true,
455                description: "TcpListener handle from io.tcp_listen()".to_string(),
456                ..Default::default()
457            }],
458            return_type: Some("IoHandle".to_string()),
459        },
460    );
461
462    module.add_function_with_schema(
463        "tcp_read",
464        network_ops::io_tcp_read,
465        ModuleFunction {
466            description: "Read from a TCP stream".to_string(),
467            params: vec![
468                ModuleParam {
469                    name: "handle".to_string(),
470                    type_name: "IoHandle".to_string(),
471                    required: true,
472                    description: "TcpStream handle".to_string(),
473                    ..Default::default()
474                },
475                ModuleParam {
476                    name: "n".to_string(),
477                    type_name: "int".to_string(),
478                    required: false,
479                    description: "Max bytes to read (default 65536)".to_string(),
480                    ..Default::default()
481                },
482            ],
483            return_type: Some("string".to_string()),
484        },
485    );
486
487    module.add_function_with_schema(
488        "tcp_write",
489        network_ops::io_tcp_write,
490        ModuleFunction {
491            description: "Write to a TCP stream".to_string(),
492            params: vec![
493                ModuleParam {
494                    name: "handle".to_string(),
495                    type_name: "IoHandle".to_string(),
496                    required: true,
497                    description: "TcpStream handle".to_string(),
498                    ..Default::default()
499                },
500                ModuleParam {
501                    name: "data".to_string(),
502                    type_name: "string".to_string(),
503                    required: true,
504                    description: "Data to send".to_string(),
505                    ..Default::default()
506                },
507            ],
508            return_type: Some("int".to_string()),
509        },
510    );
511
512    module.add_function_with_schema(
513        "tcp_close",
514        network_ops::io_tcp_close,
515        ModuleFunction {
516            description: "Close a TCP handle".to_string(),
517            params: vec![ModuleParam {
518                name: "handle".to_string(),
519                type_name: "IoHandle".to_string(),
520                required: true,
521                description: "TCP handle to close".to_string(),
522                ..Default::default()
523            }],
524            return_type: Some("bool".to_string()),
525        },
526    );
527
528    // === UDP operations ===
529
530    module.add_function_with_schema(
531        "udp_bind",
532        network_ops::io_udp_bind,
533        ModuleFunction {
534            description: "Bind a UDP socket".to_string(),
535            params: vec![ModuleParam {
536                name: "addr".to_string(),
537                type_name: "string".to_string(),
538                required: true,
539                description: "Address to bind (e.g. \"0.0.0.0:0\" for ephemeral)".to_string(),
540                ..Default::default()
541            }],
542            return_type: Some("IoHandle".to_string()),
543        },
544    );
545
546    module.add_function_with_schema(
547        "udp_send",
548        network_ops::io_udp_send,
549        ModuleFunction {
550            description: "Send a UDP datagram".to_string(),
551            params: vec![
552                ModuleParam {
553                    name: "handle".to_string(),
554                    type_name: "IoHandle".to_string(),
555                    required: true,
556                    description: "UdpSocket handle".to_string(),
557                    ..Default::default()
558                },
559                ModuleParam {
560                    name: "data".to_string(),
561                    type_name: "string".to_string(),
562                    required: true,
563                    description: "Data to send".to_string(),
564                    ..Default::default()
565                },
566                ModuleParam {
567                    name: "target".to_string(),
568                    type_name: "string".to_string(),
569                    required: true,
570                    description: "Target address (e.g. \"127.0.0.1:9000\")".to_string(),
571                    ..Default::default()
572                },
573            ],
574            return_type: Some("int".to_string()),
575        },
576    );
577
578    module.add_function_with_schema(
579        "udp_recv",
580        network_ops::io_udp_recv,
581        ModuleFunction {
582            description: "Receive a UDP datagram".to_string(),
583            params: vec![
584                ModuleParam {
585                    name: "handle".to_string(),
586                    type_name: "IoHandle".to_string(),
587                    required: true,
588                    description: "UdpSocket handle".to_string(),
589                    ..Default::default()
590                },
591                ModuleParam {
592                    name: "n".to_string(),
593                    type_name: "int".to_string(),
594                    required: false,
595                    description: "Max receive buffer size (default 65536)".to_string(),
596                    ..Default::default()
597                },
598            ],
599            return_type: Some("object".to_string()),
600        },
601    );
602
603    // === Process operations ===
604
605    module.add_function_with_schema(
606        "spawn",
607        process_ops::io_spawn,
608        ModuleFunction {
609            description: "Spawn a subprocess with piped I/O".to_string(),
610            params: vec![
611                ModuleParam {
612                    name: "cmd".to_string(),
613                    type_name: "string".to_string(),
614                    required: true,
615                    description: "Command to execute".to_string(),
616                    ..Default::default()
617                },
618                ModuleParam {
619                    name: "args".to_string(),
620                    type_name: "Vec<string>".to_string(),
621                    required: false,
622                    description: "Command arguments".to_string(),
623                    ..Default::default()
624                },
625            ],
626            return_type: Some("IoHandle".to_string()),
627        },
628    );
629
630    module.add_function_with_schema(
631        "exec",
632        process_ops::io_exec,
633        ModuleFunction {
634            description: "Run a command and capture output".to_string(),
635            params: vec![
636                ModuleParam {
637                    name: "cmd".to_string(),
638                    type_name: "string".to_string(),
639                    required: true,
640                    description: "Command to execute".to_string(),
641                    ..Default::default()
642                },
643                ModuleParam {
644                    name: "args".to_string(),
645                    type_name: "Vec<string>".to_string(),
646                    required: false,
647                    description: "Command arguments".to_string(),
648                    ..Default::default()
649                },
650            ],
651            return_type: Some("object".to_string()),
652        },
653    );
654
655    module.add_function_with_schema(
656        "process_wait",
657        process_ops::io_process_wait,
658        ModuleFunction {
659            description: "Wait for a process to exit".to_string(),
660            params: vec![ModuleParam {
661                name: "handle".to_string(),
662                type_name: "IoHandle".to_string(),
663                required: true,
664                description: "Process handle from io.spawn()".to_string(),
665                ..Default::default()
666            }],
667            return_type: Some("int".to_string()),
668        },
669    );
670
671    module.add_function_with_schema(
672        "process_kill",
673        process_ops::io_process_kill,
674        ModuleFunction {
675            description: "Kill a running process".to_string(),
676            params: vec![ModuleParam {
677                name: "handle".to_string(),
678                type_name: "IoHandle".to_string(),
679                required: true,
680                description: "Process handle from io.spawn()".to_string(),
681                ..Default::default()
682            }],
683            return_type: Some("unit".to_string()),
684        },
685    );
686
687    module.add_function_with_schema(
688        "process_write",
689        process_ops::io_process_write,
690        ModuleFunction {
691            description: "Write to a process stdin".to_string(),
692            params: vec![
693                ModuleParam {
694                    name: "handle".to_string(),
695                    type_name: "IoHandle".to_string(),
696                    required: true,
697                    description: "Process handle".to_string(),
698                    ..Default::default()
699                },
700                ModuleParam {
701                    name: "data".to_string(),
702                    type_name: "string".to_string(),
703                    required: true,
704                    description: "Data to write to stdin".to_string(),
705                    ..Default::default()
706                },
707            ],
708            return_type: Some("int".to_string()),
709        },
710    );
711
712    module.add_function_with_schema(
713        "process_read",
714        process_ops::io_process_read,
715        ModuleFunction {
716            description: "Read from a process stdout".to_string(),
717            params: vec![
718                ModuleParam {
719                    name: "handle".to_string(),
720                    type_name: "IoHandle".to_string(),
721                    required: true,
722                    description: "Process handle".to_string(),
723                    ..Default::default()
724                },
725                ModuleParam {
726                    name: "n".to_string(),
727                    type_name: "int".to_string(),
728                    required: false,
729                    description: "Max bytes to read (default 65536)".to_string(),
730                    ..Default::default()
731                },
732            ],
733            return_type: Some("string".to_string()),
734        },
735    );
736
737    module.add_function_with_schema(
738        "process_read_err",
739        process_ops::io_process_read_err,
740        ModuleFunction {
741            description: "Read from a process stderr".to_string(),
742            params: vec![
743                ModuleParam {
744                    name: "handle".to_string(),
745                    type_name: "IoHandle".to_string(),
746                    required: true,
747                    description: "Process handle".to_string(),
748                    ..Default::default()
749                },
750                ModuleParam {
751                    name: "n".to_string(),
752                    type_name: "int".to_string(),
753                    required: false,
754                    description: "Max bytes to read (default 65536)".to_string(),
755                    ..Default::default()
756                },
757            ],
758            return_type: Some("string".to_string()),
759        },
760    );
761
762    module.add_function_with_schema(
763        "process_read_line",
764        process_ops::io_process_read_line,
765        ModuleFunction {
766            description: "Read one line from process stdout".to_string(),
767            params: vec![ModuleParam {
768                name: "handle".to_string(),
769                type_name: "IoHandle".to_string(),
770                required: true,
771                description: "Process handle".to_string(),
772                ..Default::default()
773            }],
774            return_type: Some("string".to_string()),
775        },
776    );
777
778    module.add_function_with_schema(
779        "stdin",
780        process_ops::io_stdin,
781        ModuleFunction {
782            description: "Get handle for current process stdin".to_string(),
783            params: vec![],
784            return_type: Some("IoHandle".to_string()),
785        },
786    );
787
788    module.add_function_with_schema(
789        "stdout",
790        process_ops::io_stdout,
791        ModuleFunction {
792            description: "Get handle for current process stdout".to_string(),
793            params: vec![],
794            return_type: Some("IoHandle".to_string()),
795        },
796    );
797
798    module.add_function_with_schema(
799        "stderr",
800        process_ops::io_stderr,
801        ModuleFunction {
802            description: "Get handle for current process stderr".to_string(),
803            params: vec![],
804            return_type: Some("IoHandle".to_string()),
805        },
806    );
807
808    module.add_function_with_schema(
809        "read_line",
810        process_ops::io_read_line,
811        ModuleFunction {
812            description: "Read a line from a handle or stdin".to_string(),
813            params: vec![ModuleParam {
814                name: "handle".to_string(),
815                type_name: "IoHandle".to_string(),
816                required: false,
817                description: "Handle to read from (default: stdin)".to_string(),
818                ..Default::default()
819            }],
820            return_type: Some("string".to_string()),
821        },
822    );
823
824    // === Async file I/O operations ===
825
826    module.add_async_function_with_schema(
827        "read_file_async",
828        async_file_ops::io_read_file_async,
829        ModuleFunction {
830            description: "Asynchronously read entire file as a string".to_string(),
831            params: vec![ModuleParam {
832                name: "path".to_string(),
833                type_name: "string".to_string(),
834                required: true,
835                description: "File path to read".to_string(),
836                ..Default::default()
837            }],
838            return_type: Some("string".to_string()),
839        },
840    );
841
842    module.add_async_function_with_schema(
843        "write_file_async",
844        async_file_ops::io_write_file_async,
845        ModuleFunction {
846            description: "Asynchronously write a string to a file".to_string(),
847            params: vec![
848                ModuleParam {
849                    name: "path".to_string(),
850                    type_name: "string".to_string(),
851                    required: true,
852                    description: "File path to write".to_string(),
853                    ..Default::default()
854                },
855                ModuleParam {
856                    name: "data".to_string(),
857                    type_name: "string".to_string(),
858                    required: true,
859                    description: "Data to write".to_string(),
860                    ..Default::default()
861                },
862            ],
863            return_type: Some("int".to_string()),
864        },
865    );
866
867    module.add_async_function_with_schema(
868        "append_file_async",
869        async_file_ops::io_append_file_async,
870        ModuleFunction {
871            description: "Asynchronously append a string to a file".to_string(),
872            params: vec![
873                ModuleParam {
874                    name: "path".to_string(),
875                    type_name: "string".to_string(),
876                    required: true,
877                    description: "File path to append to".to_string(),
878                    ..Default::default()
879                },
880                ModuleParam {
881                    name: "data".to_string(),
882                    type_name: "string".to_string(),
883                    required: true,
884                    description: "Data to append".to_string(),
885                    ..Default::default()
886                },
887            ],
888            return_type: Some("int".to_string()),
889        },
890    );
891
892    module.add_async_function_with_schema(
893        "read_bytes_async",
894        async_file_ops::io_read_bytes_async,
895        ModuleFunction {
896            description: "Asynchronously read file as raw bytes".to_string(),
897            params: vec![ModuleParam {
898                name: "path".to_string(),
899                type_name: "string".to_string(),
900                required: true,
901                description: "File path to read".to_string(),
902                ..Default::default()
903            }],
904            return_type: Some("Array<int>".to_string()),
905        },
906    );
907
908    module.add_async_function_with_schema(
909        "exists_async",
910        async_file_ops::io_exists_async,
911        ModuleFunction {
912            description: "Asynchronously check if a path exists".to_string(),
913            params: vec![ModuleParam {
914                name: "path".to_string(),
915                type_name: "string".to_string(),
916                required: true,
917                description: "Path to check".to_string(),
918                ..Default::default()
919            }],
920            return_type: Some("bool".to_string()),
921        },
922    );
923
924    // === Gzip file I/O ===
925
926    module.add_function_with_schema(
927        "read_gzip",
928        file_ops::io_read_gzip,
929        ModuleFunction {
930            description: "Read a gzip-compressed file and return decompressed string".to_string(),
931            params: vec![ModuleParam {
932                name: "path".to_string(),
933                type_name: "string".to_string(),
934                required: true,
935                description: "Path to gzip file".to_string(),
936                ..Default::default()
937            }],
938            return_type: Some("string".to_string()),
939        },
940    );
941
942    module.add_function_with_schema(
943        "write_gzip",
944        file_ops::io_write_gzip,
945        ModuleFunction {
946            description: "Compress a string with gzip and write to a file".to_string(),
947            params: vec![
948                ModuleParam {
949                    name: "path".to_string(),
950                    type_name: "string".to_string(),
951                    required: true,
952                    description: "Output file path".to_string(),
953                    ..Default::default()
954                },
955                ModuleParam {
956                    name: "data".to_string(),
957                    type_name: "string".to_string(),
958                    required: true,
959                    description: "String data to compress and write".to_string(),
960                    ..Default::default()
961                },
962                ModuleParam {
963                    name: "level".to_string(),
964                    type_name: "int".to_string(),
965                    required: false,
966                    description: "Compression level 0-9 (default: 6)".to_string(),
967                    default_snippet: Some("6".to_string()),
968                    ..Default::default()
969                },
970            ],
971            return_type: Some("null".to_string()),
972        },
973    );
974
975    module
976}
977
978#[cfg(test)]
979mod tests {
980    use super::*;
981
982    #[test]
983    fn test_io_module_creation() {
984        let module = create_io_module();
985        assert_eq!(module.name, "std::core::io");
986
987        // File operations
988        assert!(module.has_export("open"));
989        assert!(module.has_export("read"));
990        assert!(module.has_export("read_to_string"));
991        assert!(module.has_export("read_bytes"));
992        assert!(module.has_export("write"));
993        assert!(module.has_export("close"));
994        assert!(module.has_export("flush"));
995
996        // Stat operations
997        assert!(module.has_export("exists"));
998        assert!(module.has_export("stat"));
999        assert!(module.has_export("is_file"));
1000        assert!(module.has_export("is_dir"));
1001
1002        // Directory operations
1003        assert!(module.has_export("mkdir"));
1004        assert!(module.has_export("remove"));
1005        assert!(module.has_export("rename"));
1006        assert!(module.has_export("read_dir"));
1007
1008        // Path operations
1009        assert!(module.has_export("join"));
1010        assert!(module.has_export("dirname"));
1011        assert!(module.has_export("basename"));
1012        assert!(module.has_export("extension"));
1013        assert!(module.has_export("resolve"));
1014
1015        // TCP operations
1016        assert!(module.has_export("tcp_connect"));
1017        assert!(module.has_export("tcp_listen"));
1018        assert!(module.has_export("tcp_accept"));
1019        assert!(module.has_export("tcp_read"));
1020        assert!(module.has_export("tcp_write"));
1021        assert!(module.has_export("tcp_close"));
1022
1023        // UDP operations
1024        assert!(module.has_export("udp_bind"));
1025        assert!(module.has_export("udp_send"));
1026        assert!(module.has_export("udp_recv"));
1027
1028        // Process operations
1029        assert!(module.has_export("spawn"));
1030        assert!(module.has_export("exec"));
1031        assert!(module.has_export("process_wait"));
1032        assert!(module.has_export("process_kill"));
1033        assert!(module.has_export("process_write"));
1034        assert!(module.has_export("process_read"));
1035        assert!(module.has_export("process_read_err"));
1036        assert!(module.has_export("process_read_line"));
1037
1038        // Std stream operations
1039        assert!(module.has_export("stdin"));
1040        assert!(module.has_export("stdout"));
1041        assert!(module.has_export("stderr"));
1042        assert!(module.has_export("read_line"));
1043
1044        // Async file I/O operations
1045        assert!(module.has_export("read_file_async"));
1046        assert!(module.has_export("write_file_async"));
1047        assert!(module.has_export("append_file_async"));
1048        assert!(module.has_export("read_bytes_async"));
1049        assert!(module.has_export("exists_async"));
1050    }
1051
1052    #[test]
1053    fn test_io_module_schemas() {
1054        let module = create_io_module();
1055
1056        let open_schema = module.get_schema("open").unwrap();
1057        assert_eq!(open_schema.params.len(), 2);
1058        assert_eq!(open_schema.return_type.as_deref(), Some("IoHandle"));
1059
1060        let write_schema = module.get_schema("write").unwrap();
1061        assert_eq!(write_schema.params.len(), 2);
1062
1063        let exists_schema = module.get_schema("exists").unwrap();
1064        assert_eq!(exists_schema.return_type.as_deref(), Some("bool"));
1065
1066        // Network schemas
1067        let tcp_connect = module.get_schema("tcp_connect").unwrap();
1068        assert_eq!(tcp_connect.params.len(), 1);
1069        assert_eq!(tcp_connect.return_type.as_deref(), Some("IoHandle"));
1070
1071        let tcp_read = module.get_schema("tcp_read").unwrap();
1072        assert_eq!(tcp_read.params.len(), 2);
1073        assert_eq!(tcp_read.return_type.as_deref(), Some("string"));
1074
1075        let udp_send = module.get_schema("udp_send").unwrap();
1076        assert_eq!(udp_send.params.len(), 3);
1077        assert_eq!(udp_send.return_type.as_deref(), Some("int"));
1078
1079        let udp_recv = module.get_schema("udp_recv").unwrap();
1080        assert_eq!(udp_recv.params.len(), 2);
1081        assert_eq!(udp_recv.return_type.as_deref(), Some("object"));
1082    }
1083
1084    #[test]
1085    fn test_io_module_export_count() {
1086        let module = create_io_module();
1087        let names = module.export_names();
1088        assert_eq!(names.len(), 48); // 20 file/path + 9 network + 8 process + 4 std streams + 5 async + 2 gzip
1089    }
1090}