Cactus/fs_manager/
utils.rs

1use log::info;
2use std::{
3    fs::{self, File, OpenOptions},
4    io::{self, Write},
5    path::Path,
6};
7
8/// Appends `content` to a file located at `path`.
9pub fn append_file(path: &Path, content: &str) -> io::Result<()> {
10    OpenOptions::new()
11        .append(true)
12        .open(path)?
13        .write_all(content.as_bytes())
14}
15
16/// Creates a file if it does not already exist.
17/// If the file already exists, it doesn't modify its content.
18pub fn create_file(path: &Path, content: Option<&str>) -> io::Result<()> {
19    match OpenOptions::new().write(true).create_new(true).open(path) {
20        Ok(mut file) => content.map_or_else(
21            || {
22                info!("Created an empty file: '{}'", path.display());
23                Ok(())
24            },
25            |s| {
26                file.write_all(s.as_bytes())
27                    .inspect(|_| info!("File '{}' created.", path.display()))
28            },
29        ),
30        Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {
31            info!("File '{}' already exists. Not altering it.", path.display());
32            Ok(())
33        }
34        Err(e) => Err(e),
35    }
36}
37
38/// Creates a directory given its path.
39pub fn create_dir(path: &Path) -> io::Result<()> {
40    if path.exists() {
41        info!(
42            "Directory '{}' already exists. Not altering it.",
43            path.display()
44        );
45        return Ok(());
46    }
47    fs::create_dir(path).inspect(|_| info!("Created directory: '{}'", path.display()))
48}
49
50/// Opens an already existing file and overwrites all content with `content`.
51pub fn overwrite_file(path: &Path, content: &str) -> std::io::Result<()> {
52    let mut file = File::create(path)?;
53    file.write_all(content.as_bytes())
54        .inspect(|_| info!("Overwrote file: '{}'", path.display()))
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use std::fs;
61    use tempfile::NamedTempFile;
62    use tempfile::TempDir;
63
64    #[test]
65    fn test_overwrite_file() {
66        // Create a temporary file
67        let temp_file = NamedTempFile::new().expect("Failed to create temp file");
68        let file_path = temp_file.path();
69
70        // Test 1: Write to the file
71        let content = "Hello, World!";
72        overwrite_file(file_path, content).expect("Failed to write to file");
73        assert_eq!(fs::read_to_string(file_path).unwrap(), content);
74
75        // Test 2: Overwrite existing content
76        let new_content = "New content";
77        overwrite_file(file_path, new_content).expect("Failed to overwrite file");
78        assert_eq!(fs::read_to_string(file_path).unwrap(), new_content);
79
80        // Test 3: Write empty string
81        overwrite_file(file_path, "").expect("Failed to write empty string");
82        assert_eq!(fs::read_to_string(file_path).unwrap(), "");
83
84        // Test 4: Write unicode content
85        let unicode_content = "こんにちは世界";
86        overwrite_file(file_path, unicode_content).expect("Failed to write unicode content");
87        assert_eq!(fs::read_to_string(file_path).unwrap(), unicode_content);
88    }
89
90    #[test]
91    fn test_create_file() -> io::Result<()> {
92        let temp_dir = TempDir::new()?;
93
94        // Test 1: Create a new file
95        let file_path = temp_dir.path().join("test1.txt");
96        let content = "Hello, World!";
97        create_file(&file_path, Some(content))?;
98        assert!(file_path.exists());
99        assert_eq!(fs::read_to_string(&file_path)?, content);
100
101        // Test 2: Attempt to create an existing file (should not modify)
102        let existing_content = fs::read_to_string(&file_path)?;
103        create_file(&file_path, Some("New content"))?;
104        assert_eq!(fs::read_to_string(&file_path)?, existing_content);
105
106        // Test 3: Create file with empty content
107        let empty_file_path = temp_dir.path().join("empty.txt");
108        create_file(&empty_file_path, Some(""))?;
109        assert!(empty_file_path.exists());
110        assert_eq!(fs::read_to_string(&empty_file_path)?, "");
111
112        Ok(())
113    }
114}