ys1r/
io.rs

1use std::error::Error;
2use std::fs::{self, File};
3use std::io::{BufRead, BufReader, Write};
4
5/// Reads the content of a file into a String.
6///
7/// # Arguments
8///
9/// * `file_name` - The path to the file to read.
10///
11/// # Returns
12///
13/// A `Result` containing the content of the file as a `String`, or an error if the file could not be read.
14pub fn file_read(file_name: &str) -> Result<String, Box<dyn Error>> {
15    let content = fs::read_to_string(file_name)?;
16    Ok(content)
17}
18
19/// Writes a string to a file.
20///
21/// # Arguments
22///
23/// * `file_name` - The path to the file to write to.
24/// * `content` - The content to write to the file.
25///
26/// # Returns
27///
28/// A `Result` indicating success or an error if the file could not be written.
29pub fn file_write(file_name: &str, content: &str) -> Result<(), Box<dyn Error>> {
30    let mut file = File::create(file_name)?;
31    file.write_all(content.as_bytes())?;
32    Ok(())
33}
34
35/// Processes each line of a file with a given function.
36///
37/// # Arguments
38///
39/// * `file_name` - The path to the file to process.
40/// * `f` - A function to apply to each line of the file.
41///
42/// # Returns
43///
44/// A `Result` indicating success or an error if the file could not be read.
45/// 
46/// # Examples
47///
48/// ```
49/// let mut i: i32 = 1;
50/// let _ = ys1r::io::process_file_lines("Cargo.toml", |line| {
51///   println!("{}: {}", i, line.replace("y", "Y"));
52///   i += 1;
53/// });
54/// ```
55pub fn process_file_lines<F>(file_name: &str, mut f: F) -> Result<(), Box<dyn Error>>
56where
57    F: FnMut(&str),
58{
59    let file = File::open(file_name)?;
60    let reader = BufReader::new(file);
61
62    for line_result in reader.lines() {
63        let line = line_result?;
64        f(&line);
65    }
66
67    Ok(())
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use std::fs;
74    use std::io::Write;
75
76    #[test]
77    fn test_file_read_write() -> Result<(), Box<dyn Error>> {
78        let file_name = "test_file.txt";
79        let content_a = "HELLO WORLD!";
80
81        file_write(file_name, content_a)?;
82
83        let content_b = file_read(file_name)?;
84
85        assert_eq!(content_b, content_a);
86        fs::remove_file(file_name)?;
87        Ok(())
88    }
89
90    #[test]
91    fn test_process_file_lines() -> Result<(), Box<dyn Error>> {
92        let mut path = std::env::temp_dir();
93        path.push("test_file_lines.txt");
94        let content = "rust\nruby\nr\n";
95        let mut file = File::create(&path)?;
96        file.write_all(content.as_bytes())?;
97
98        let mut collected = Vec::new();
99        process_file_lines(path.to_str().unwrap(), |line| {
100            let modified_line = line.replace("r", "R");
101            collected.push(modified_line);
102        })?;
103
104        assert_eq!(collected, vec!["Rust", "Ruby", "R"]);
105
106        fs::remove_file(path)?;
107        Ok(())
108    }
109}