use std::fs::{File, OpenOptions};
use std::io::{self, BufRead, BufReader, Write};
pub struct FileIO {
path: String,
}
impl FileIO {
pub fn new(path: &str) -> Self {
Self { path: path.to_string() }
}
pub fn read_all(&self) -> io::Result<String> {
std::fs::read_to_string(&self.path)
}
pub fn read_lines(&self) -> io::Result<Vec<String>> {
let file = File::open(&self.path)?;
let reader = BufReader::new(file);
reader.lines().collect()
}
pub fn append(&self, content: &str) -> io::Result<()> {
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open(&self.path)?;
writeln!(file, "{}", content)?;
Ok(())
}
pub fn write(&self, content: &str) -> io::Result<()> {
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(&self.path)?;
file.write_all(content.as_bytes())
}
pub fn write_line(&self, line_number: usize, content: &str) -> io::Result<()> {
if line_number == 0 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"line_number must be >= 1",
));
}
let mut lines = self.read_lines().unwrap_or_default();
if line_number > lines.len() {
lines.resize(line_number, String::new());
}
lines[line_number - 1] = content.to_string();
self.write(&lines.join("\n"))
}
pub fn insert_line(&self, line_number: usize, content: &str) -> io::Result<()> {
if line_number == 0 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"line_number must be >= 1",
));
}
let mut lines = self.read_lines().unwrap_or_default();
if line_number > lines.len() + 1 {
lines.resize(line_number - 1, String::new());
}
lines.insert(line_number - 1, content.to_string());
self.write(&lines.join("\n"))
}
}
pub fn file(path: &str) -> FileIO {
FileIO::new(path)
}