subx_cli/core/
file_manager.rs

1use std::fs;
2use std::path::{Path, PathBuf};
3
4use crate::{Result, error::SubXError};
5
6/// 安全的檔案操作管理器,用於追蹤檔案建立與移除操作,並在需要時進行回滾。
7pub struct FileManager {
8    operations: Vec<FileOperation>,
9}
10
11#[cfg(test)]
12mod tests {
13    use super::*;
14    use std::fs;
15    use tempfile::TempDir;
16
17    #[test]
18    fn test_file_manager_remove_and_rollback() {
19        let temp_dir = TempDir::new().unwrap();
20        let file_path = temp_dir.path().join("test.txt");
21        fs::write(&file_path, "test content").unwrap();
22
23        let mut manager = FileManager::new();
24        manager.remove_file(&file_path).unwrap();
25        assert!(!file_path.exists(), "檔案應已移除");
26
27        // 測試回滾建立的檔案
28        let new_file = temp_dir.path().join("new.txt");
29        fs::write(&new_file, "content").unwrap();
30        manager.record_creation(&new_file);
31        manager.rollback().unwrap();
32        assert!(!new_file.exists(), "建立的檔案應已回滾移除");
33    }
34}
35
36/// 檔案操作類型:建立或移除
37#[derive(Debug)]
38enum FileOperation {
39    Created(PathBuf),
40    Removed(PathBuf),
41}
42
43impl FileManager {
44    /// 建立新的檔案管理器
45    pub fn new() -> Self {
46        Self {
47            operations: Vec::new(),
48        }
49    }
50
51    /// 記錄檔案建立操作
52    pub fn record_creation<P: AsRef<Path>>(&mut self, path: P) {
53        self.operations
54            .push(FileOperation::Created(path.as_ref().to_path_buf()));
55    }
56
57    /// 安全地移除檔案
58    pub fn remove_file<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
59        let path_buf = path.as_ref().to_path_buf();
60        if !path_buf.exists() {
61            return Err(SubXError::FileNotFound(
62                path_buf.to_string_lossy().to_string(),
63            ));
64        }
65        fs::remove_file(&path_buf).map_err(|e| SubXError::FileOperationFailed(e.to_string()))?;
66        self.operations
67            .push(FileOperation::Removed(path_buf.clone()));
68        println!("🗑️  已移除原始檔案: {}", path_buf.display());
69        Ok(())
70    }
71
72    /// 回滾所有已記錄的操作,依逆序執行
73    pub fn rollback(&mut self) -> Result<()> {
74        for op in self.operations.drain(..).rev() {
75            match op {
76                FileOperation::Created(path) => {
77                    if path.exists() {
78                        fs::remove_file(&path)
79                            .map_err(|e| SubXError::FileOperationFailed(e.to_string()))?;
80                        println!("🔄 已回滾建立的檔案: {}", path.display());
81                    }
82                }
83                FileOperation::Removed(_) => {
84                    // 已移除的檔案無法恢復,僅記錄警告
85                    eprintln!("⚠️  警告:無法恢復已移除的檔案");
86                }
87            }
88        }
89        Ok(())
90    }
91}
92
93impl Default for FileManager {
94    fn default() -> Self {
95        FileManager::new()
96    }
97}