Skip to main content

windjammer_runtime/
io.rs

1//! I/O utilities
2//!
3//! Windjammer's io module provides buffered reading and writing capabilities
4//! with simplified error handling.
5
6use std::fs::File;
7use std::io::{
8    BufRead as StdBufRead, BufReader as StdBufReader, BufWriter as StdBufWriter, Read as StdRead,
9    Write as StdWrite,
10};
11
12/// Re-export std::io types
13pub use std::io::{BufRead, BufReader, BufWriter, Error, Read, Result, Write};
14
15/// Check if stdout is connected to a terminal (tty)
16pub fn is_terminal() -> bool {
17    use std::io::IsTerminal;
18    std::io::stdout().is_terminal()
19}
20
21/// Create a buffered reader from a file
22pub fn buf_reader(file: File) -> StdBufReader<File> {
23    StdBufReader::new(file)
24}
25
26/// Create a buffered writer from a file
27pub fn buf_writer(file: File) -> StdBufWriter<File> {
28    StdBufWriter::new(file)
29}
30
31/// Read all lines from a buffered reader
32pub fn read_lines<R: StdBufRead>(reader: R) -> Vec<String> {
33    reader.lines().map_while(Result::ok).collect()
34}
35
36/// Read all bytes from a reader
37pub fn read_all<R: StdRead>(mut reader: R) -> Result<Vec<u8>> {
38    let mut buffer = Vec::new();
39    reader.read_to_end(&mut buffer)?;
40    Ok(buffer)
41}
42
43/// Read all text from a reader
44pub fn read_to_string<R: StdRead>(mut reader: R) -> Result<String> {
45    let mut buffer = String::new();
46    reader.read_to_string(&mut buffer)?;
47    Ok(buffer)
48}
49
50/// Write all bytes to a writer
51pub fn write_all<W: StdWrite>(mut writer: W, data: &[u8]) -> Result<()> {
52    writer.write_all(data)
53}
54
55/// Write a string to a writer
56pub fn write_str<W: StdWrite>(mut writer: W, s: &str) -> Result<()> {
57    writer.write_all(s.as_bytes())
58}
59
60/// Flush a writer
61pub fn flush<W: StdWrite>(mut writer: W) -> Result<()> {
62    writer.flush()
63}
64
65/// stdin handle
66pub fn stdin() -> std::io::Stdin {
67    std::io::stdin()
68}
69
70/// stdout handle
71pub fn stdout() -> std::io::Stdout {
72    std::io::stdout()
73}
74
75/// stderr handle
76pub fn stderr() -> std::io::Stderr {
77    std::io::stderr()
78}
79
80/// Read a line from stdin
81pub fn read_line() -> Result<String> {
82    let mut buffer = String::new();
83    stdin().read_line(&mut buffer)?;
84    Ok(buffer.trim_end().to_string())
85}
86
87/// Print to stdout
88pub fn print(s: &str) {
89    print!("{}", s);
90}
91
92/// Print to stdout with newline
93pub fn println(s: &str) {
94    println!("{}", s);
95}
96
97/// Print to stderr
98pub fn eprint(s: &str) {
99    eprint!("{}", s);
100}
101
102/// Print to stderr with newline
103pub fn eprintln(s: &str) {
104    eprintln!("{}", s);
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_read_lines() {
113        let data = b"line1\nline2\nline3";
114        let reader = std::io::Cursor::new(data);
115        let lines = read_lines(StdBufReader::new(reader));
116
117        assert_eq!(lines.len(), 3);
118        assert_eq!(lines[0], "line1");
119        assert_eq!(lines[1], "line2");
120        assert_eq!(lines[2], "line3");
121    }
122
123    #[test]
124    fn test_read_all() {
125        let data = b"hello world";
126        let reader = std::io::Cursor::new(data);
127        let result = read_all(reader).unwrap();
128
129        assert_eq!(result, data);
130    }
131
132    #[test]
133    fn test_write_operations() {
134        let mut buffer = Vec::new();
135        write_str(&mut buffer, "hello").unwrap();
136        assert_eq!(buffer, b"hello");
137
138        write_all(&mut buffer, b" world").unwrap();
139        assert_eq!(buffer, b"hello world");
140    }
141}