Skip to main content

lua_std/
io.rs

1//! The input and output library.
2//!
3//! I/O operations come in two styles. The *simple* style uses implicit
4//! default files: [`io.read`](read()) and [`io.write`](write()) operate on
5//! the current input and output files, set with [`input`] and [`output`].
6//! The *complete* style uses explicit [`file`](struct@file) handles
7//! returned by [`open`], with the operations available as methods:
8//!
9//! ```lua
10//! local f = assert(io.open("notes.txt", "r"))
11//! for line in f:lines() do
12//!   print(line)
13//! end
14//! f:close()
15//! ```
16//!
17//! The library also provides three predefined handles: [`stdin`],
18//! [`stdout`] and [`stderr`].
19
20use crate::{any, boolean, function, number, option, string, Repeatable};
21
22/// The standard input file handle.
23///
24/// ```lua
25/// local line = io.stdin:read("l")
26/// ```
27pub static stdin: file = file;
28
29/// The standard output file handle.
30///
31/// ```lua
32/// io.stdout:write("hello\n")
33/// ```
34pub static stdout: file = file;
35
36/// The standard error file handle.
37///
38/// ```lua
39/// io.stderr:write("something went wrong\n")
40/// ```
41pub static stderr: file = file;
42
43/// A handle to an open file.
44///
45/// File handles are full userdata values with a shared metatable, so
46/// every operation is available in method form (`f:read(...)`). When a
47/// file handle is collected without being closed, its finalizer closes
48/// the file.
49pub struct file;
50
51impl file {
52    /// Closes a file.
53    ///
54    /// # Return value
55    ///
56    /// True on success. Note that files are automatically closed when
57    /// their handles are garbage collected, but that takes an
58    /// unpredictable amount of time to happen.
59    ///
60    /// # Examples
61    ///
62    /// ```lua
63    /// local f = assert(io.open("notes.txt"))
64    /// print(f:read("a"))
65    /// f:close()
66    /// ```
67    pub fn close(&self) -> boolean {
68        todo!()
69    }
70
71    /// Flushes a file's output buffer.
72    ///
73    /// # Description
74    ///
75    /// Saves any written data to the file. Useful to make sure output is
76    /// visible before the file is closed — for example, when writing a
77    /// progress log that another process is watching.
78    ///
79    /// # Examples
80    ///
81    /// ```lua
82    /// log:write("step 3 done\n")
83    /// log:flush()
84    /// ```
85    ///
86    /// # See also
87    ///
88    /// [`setvbuf`](file::setvbuf)
89    pub fn flush(&self) {
90        todo!()
91    }
92
93    /// Returns an iterator over the file's contents.
94    ///
95    /// # Parameters
96    ///
97    /// - **`···`**: read formats, as in [`read`](file::read) (default
98    ///   `"l"`, read a line).
99    ///
100    /// # Return value
101    ///
102    /// An iterator function that, each time it is called, reads the file
103    /// according to the given formats. When the iterator reaches the end
104    /// of the file, it returns `nil`. Unlike [`io.lines`](lines()), this
105    /// form does *not* close the file when the loop ends.
106    ///
107    /// # Examples
108    ///
109    /// ```lua
110    /// local f = assert(io.open("data.txt"))
111    /// for line in f:lines() do
112    ///   print(line)
113    /// end
114    /// f:close()
115    /// ```
116    pub fn lines(&self, formats: Repeatable<string>) -> function {
117        todo!()
118    }
119
120    /// Reads from a file.
121    ///
122    /// # Parameters
123    ///
124    /// - **`···`**: one or more read formats: `"n"` reads a numeral,
125    ///   `"a"` reads the whole file from the current position, `"l"`
126    ///   reads the next line dropping the newline (the default), `"L"`
127    ///   reads the next line keeping the newline, and a number reads that
128    ///   many bytes.
129    ///
130    /// # Return value
131    ///
132    /// For each format, a string or a number with the characters read,
133    /// or `nil` if it cannot read data with that format (e.g. at end of
134    /// file).
135    ///
136    /// # Examples
137    ///
138    /// ```lua
139    /// local f = assert(io.open("data.txt"))
140    /// local first = f:read("l")     -- one line
141    /// local rest  = f:read("a")     -- everything else
142    /// local n     = io.stdin:read("n")   -- a number from stdin
143    /// ```
144    ///
145    /// # See also
146    ///
147    /// [`lines`](file::lines), [`io.read`](read())
148    pub fn read(&self, formats: Repeatable<string>) -> Repeatable<any> {
149        todo!()
150    }
151
152    /// Sets and gets the file position.
153    ///
154    /// # Parameters
155    ///
156    /// - **`whence`**: the base for the offset: `"set"` (the beginning
157    ///   of the file), `"cur"` (the current position — the default), or
158    ///   `"end"` (the end of the file).
159    /// - **`offset`**: an offset in bytes from the base (default 0).
160    ///
161    /// # Return value
162    ///
163    /// The resulting file position, measured in bytes from the beginning
164    /// of the file, or `nil` plus an error message on failure. The
165    /// no-argument call `f:seek()` reads the current position without
166    /// changing it, and `f:seek("end")` returns the file size.
167    ///
168    /// # Examples
169    ///
170    /// ```lua
171    /// local size = f:seek("end")    -- file size in bytes
172    /// f:seek("set")                 -- rewind to the start
173    /// f:seek("cur", 16)             -- skip 16 bytes
174    /// ```
175    pub fn seek(&self, whence: option<string>, offset: option<number>) -> option<number> {
176        todo!()
177    }
178
179    /// Sets the buffering mode for a file.
180    ///
181    /// # Parameters
182    ///
183    /// - **`mode`**: `"no"` (no buffering: output appears immediately),
184    ///   `"full"` (output is flushed when the buffer fills or the file
185    ///   is closed), or `"line"` (output is buffered until a newline is
186    ///   written).
187    /// - **`size`**: a hint for the buffer size, in bytes.
188    ///
189    /// # Examples
190    ///
191    /// ```lua
192    /// log:setvbuf("line")    -- flush the log after every line
193    /// ```
194    ///
195    /// # See also
196    ///
197    /// [`flush`](file::flush)
198    pub fn setvbuf(&self, mode: string, size: option<number>) {
199        todo!()
200    }
201
202    /// Writes to a file.
203    ///
204    /// # Parameters
205    ///
206    /// - **`···`**: strings or numbers to write. Other values must be
207    ///   converted first (with [`tostring`](crate::tostring()) or
208    ///   `string.format`).
209    ///
210    /// # Return value
211    ///
212    /// The file itself, so write calls can be chained; on error, `nil`
213    /// plus an error message.
214    ///
215    /// # Examples
216    ///
217    /// ```lua
218    /// f:write("x = "):write(42):write("\n")
219    /// io.stdout:write("no newline is added")
220    /// ```
221    ///
222    /// # See also
223    ///
224    /// [`io.write`](write())
225    pub fn write(&self, values: Repeatable<any>) -> file {
226        todo!()
227    }
228}
229
230/// Closes a file, or the default output file.
231///
232/// # Parameters
233///
234/// - **`file`**: the file handle to close (default: the current default
235///   output file).
236///
237/// # Return value
238///
239/// True on success. Equivalent to `file:close()`.
240///
241/// # Examples
242///
243/// ```lua
244/// io.output("log.txt")
245/// io.write("done\n")
246/// io.close()               -- closes log.txt
247/// ```
248///
249/// # See also
250///
251/// [`file::close`]
252pub fn close(f: option<file>) -> boolean {
253    todo!()
254}
255
256/// Flushes the default output file.
257///
258/// # Description
259///
260/// Saves any written data to the default output file. Equivalent to
261/// `io.output():flush()`.
262///
263/// # Examples
264///
265/// ```lua
266/// io.write("working...")
267/// io.flush()               -- make it visible before a newline arrives
268/// ```
269///
270/// # See also
271///
272/// [`file::flush`]
273pub fn flush() {
274    todo!()
275}
276
277/// Sets or gets the default input file.
278///
279/// # Parameters
280///
281/// - **`file`**: a file name to open in text mode, or an already open
282///   file handle, to become the new default input file. When absent, the
283///   function only queries.
284///
285/// # Return value
286///
287/// The current default input file. When setting, raises an error if the
288/// file name cannot be opened.
289///
290/// # Examples
291///
292/// ```lua
293/// io.input("data.txt")        -- read from data.txt from now on
294/// print(io.read("l"))         -- first line of data.txt
295/// io.input(io.stdin)          -- back to stdin
296/// ```
297///
298/// # See also
299///
300/// [`output`], [`io.read`](read())
301pub fn input(f: option<any>) -> file {
302    todo!()
303}
304
305/// Iterates over the lines of a named file.
306///
307/// # Parameters
308///
309/// - **`filename`**: the file to open in read mode. When absent,
310///   iterates over the default input file.
311/// - **`···`**: read formats, as in [`file::read`] (default `"l"`).
312///
313/// # Return value
314///
315/// An iterator function. Unlike [`file::lines`], this form *closes the
316/// file automatically* when the loop ends, when it fails, or when it is
317/// interrupted by a `break` inside a generic for.
318///
319/// # Examples
320///
321/// ```lua
322/// for line in io.lines("notes.txt") do
323///   print(line)
324/// end
325/// ```
326///
327/// # See also
328///
329/// [`file::lines`], [`open`]
330pub fn lines(filename: option<string>, formats: Repeatable<string>) -> function {
331    todo!()
332}
333
334/// Opens a file.
335///
336/// # Parameters
337///
338/// - **`filename`**: the name of the file to open.
339/// - **`mode`**: the open mode: `"r"` (read — the default), `"w"`
340///   (write, truncating), `"a"` (append), or the update modes `"r+"`,
341///   `"w+"`, `"a+"`. Any of them may be followed by `"b"` to open in
342///   binary mode on systems where it matters.
343///
344/// # Return value
345///
346/// A new file handle, or, in case of errors, `nil` plus an error message
347/// and a system-dependent error code. A common idiom wraps the call in
348/// [`assert`](crate::assert) to turn a failed open into an error.
349///
350/// # Examples
351///
352/// ```lua
353/// local f = assert(io.open("out.txt", "w"))
354/// f:write("hello\n")
355/// f:close()
356/// ```
357///
358/// # See also
359///
360/// [`lines`], [`close`]
361pub fn open(filename: string, mode: option<string>) -> option<file> {
362    todo!()
363}
364
365/// Sets or gets the default output file.
366///
367/// # Parameters
368///
369/// - **`file`**: a file name or an open handle to become the new default
370///   output file. When absent, the function only queries.
371///
372/// # Return value
373///
374/// The current default output file. Works like [`input`], but for
375/// output.
376///
377/// # Examples
378///
379/// ```lua
380/// io.output("log.txt")
381/// io.write("logged\n")        -- goes to log.txt
382/// io.output(io.stdout)        -- back to stdout
383/// ```
384///
385/// # See also
386///
387/// [`input`], [`io.write`](write())
388pub fn output(f: option<any>) -> file {
389    todo!()
390}
391
392/// Starts a program and connects to it with a pipe.
393///
394/// # Parameters
395///
396/// - **`prog`**: the command to run in a separate process.
397/// - **`mode`**: `"r"` to read the program's output (the default) or
398///   `"w"` to write to the program's input.
399///
400/// # Return value
401///
402/// A file handle connected to the program, or `nil` plus an error
403/// message. This function is system dependent and is not available on
404/// all platforms.
405///
406/// # Examples
407///
408/// ```lua
409/// local p = assert(io.popen("ls -1"))
410/// for name in p:lines() do
411///   print(name)
412/// end
413/// p:close()
414/// ```
415///
416/// # See also
417///
418/// [`os::execute`](crate::os::execute)
419pub fn popen(prog: string, mode: option<string>) -> option<file> {
420    todo!()
421}
422
423/// Reads from the default input file.
424///
425/// # Parameters
426///
427/// - **`···`**: read formats, as in [`file::read`] (default `"l"`).
428///
429/// # Return value
430///
431/// The values read. Equivalent to `io.input():read(···)`.
432///
433/// # Examples
434///
435/// ```lua
436/// io.write("what's your name? ")
437/// local name = io.read("l")
438/// print("hello, " .. name)
439/// ```
440///
441/// # See also
442///
443/// [`file::read`], [`input`]
444pub fn read(formats: Repeatable<string>) -> Repeatable<any> {
445    todo!()
446}
447
448/// Returns a handle for a temporary file.
449///
450/// # Return value
451///
452/// A handle for a temporary file, opened in update mode and
453/// automatically removed when the program ends.
454///
455/// # Examples
456///
457/// ```lua
458/// local scratch = io.tmpfile()
459/// scratch:write("intermediate data")
460/// scratch:seek("set")
461/// print(scratch:read("a"))    --> intermediate data
462/// ```
463///
464/// # See also
465///
466/// [`os::tmpname`](crate::os::tmpname)
467pub fn tmpfile() -> file {
468    todo!()
469}
470
471/// Checks whether a value is a file handle.
472///
473/// # Parameters
474///
475/// - **`obj`**: any value.
476///
477/// # Return value
478///
479/// The string `"file"` if `obj` is an open file handle, `"closed file"`
480/// if it is a closed file handle, or `nil` if it is not a file handle.
481///
482/// # Examples
483///
484/// ```lua
485/// local f = assert(io.open("notes.txt"))
486/// print(io.type(f))       --> file
487/// f:close()
488/// print(io.type(f))       --> closed file
489/// print(io.type("hi"))    --> nil
490/// ```
491pub fn r#type(obj: any) -> option<string> {
492    todo!()
493}
494
495/// Writes to the default output file.
496///
497/// # Parameters
498///
499/// - **`···`**: strings or numbers to write.
500///
501/// # Return value
502///
503/// The default output file. Equivalent to `io.output():write(···)`.
504/// Unlike [`print`](crate::print), no separators or newline are added.
505///
506/// # Examples
507///
508/// ```lua
509/// io.write("1 + 1 = ", 1 + 1, "\n")    --> 1 + 1 = 2
510/// ```
511///
512/// # See also
513///
514/// [`file::write`], [`print`](crate::print)
515pub fn write(values: Repeatable<any>) -> file {
516    todo!()
517}